魔法猪学院
Time Limit: 10 Sec Memory Limit: 64 MB
Description
iPig在假期来到了传说中的魔法猪学院,开始为期两个月的魔法猪训练。
经过了一周理论知识和一周基本魔法的学习之后,iPig对猪世界的世界本原有了很多的了解:众所周知,世界是由元素构成的;元素与元素之间可以互相转换;能量守恒……。
iPig 今天就在进行一个麻烦的测验。
iPig 在之前的学习中已经知道了很多种元素,并学会了可以转化这些元素的魔法,每种魔法需要消耗 iPig 一定的能量。
作为 PKU 的顶尖学猪,让 iPig 用最少的能量完成从一种元素转换到另一种元素……等等,iPig 的魔法导猪可没这么笨!
这一次,他给 iPig 带来了很多 1 号元素的样本,要求 iPig 使用学习过的魔法将它们一个个转化为 N 号元素,为了增加难度,要求每份样本的转换过程都不相同。
这个看似困难的任务实际上对 iPig 并没有挑战性,因为,他有坚实的后盾……现在的你呀!
注意,两个元素之间的转化可能有多种魔法,转化是单向的。
转化的过程中,可以转化到一个元素(包括开始元素)多次,但是一但转化到目标元素,则一份样本的转化过程结束。
iPig 的总能量是有限的,所以最多能够转换的样本数一定是一个有限数。具体请参看样例。
第一行三个数 N、M、E 表示iPig知道的元素个数(元素从 1 到 N 编号)、iPig已经学会的魔法个数和iPig的总能量。
后跟 M 行每行三个数 si、ti、ei 表示 iPig 知道一种魔法,消耗 ei 的能量将元素 si 变换到元素 ti 。
Output
一行一个数,表示最多可以完成的方式数。输入数据保证至少可以完成一种方式。
4 6 14.9
1 2 1.5
2 1 1.5
1 3 3
2 3 1.5
3 4 1.5
1 4 1.5
Sample Output
3
HINT
占总分不小于 10% 的数据满足 N <= 6,M<=15。
占总分不小于 20% 的数据满足 N <= 100,M<=300,E<=100且E和所有的ei均为整数(可以直接作为整型数字读入)。
所有数据满足 2 <= N <= 5000,1 <= M <= 200000,1<=E<=107,1<=ei<=E,E和所有的ei为实数。
Main idea
询问第一个满足1~k短路的和>E的k。
Solution
求k短路,直接运用A*搜索即可,把T->每个点的最短路当做估价即可。
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| #include<bits/stdc++.h> using namespace std; typedef long long s64;
const int ONE = 205000; const int POI = 5500; const double INF = 1e18;
int n,m; int S,T; double dist[POI],w[ONE],E; bool vis[POI]; int next[ONE],first[POI],go[ONE],tot; int Ans;
struct point { int x,y; double z; }a[ONE];
struct power { int x; double real; bool operator <(const power &a) const { return a.real + dist[a.x] < real + dist[x]; } };
inline int get() { int res=1,Q=1; char c; while( (c=getchar())<48 || c>57) if(c=='-')Q=-1; if(Q) res=c-48; while((c=getchar())>=48 && c<=57) res=res*10+c-48; return res*Q; }
void Add(int u,int v,double z) { next[++tot]=first[u]; first[u]=tot; go[tot]=v; w[tot]=z; }
void SPFA(int x) { queue <int> q; q.push(x); for(int i=S;i<=T;i++) dist[i] = INF; vis[x] = 1; dist[x] = 0; while(!q.empty()) { int u = q.front(); q.pop(); for(int e=first[u];e;e=next[e]) { int v = go[e]; if(dist[v] > dist[u] + w[e]) { dist[v] = dist[u] + w[e]; if(!vis[v]) vis[v] = 1, q.push(v); } } vis[u] = 0; } }
void Astar() { priority_queue <power> q; q.push( (power){S, 0} ); while(!q.empty()) { power u = q.top(); q.pop(); if(u.x == T) {E -= u.real; if(E < 0) return; Ans++;} if(u.real + dist[u.x] > E) continue; for(int e=first[u.x]; e; e=next[e]) q.push( (power){go[e], u.real+w[e]} );
} }
int main() { n=get(); m=get(); scanf("%lf",&E); S=1, T=n; for(int i=1;i<=m;i++) { a[i].x=get(); a[i].y=get(); scanf("%lf",&a[i].z); Add(a[i].y, a[i].x, a[i].z); } SPFA(T);
memset(first,0,sizeof(first)); tot=0; for(int i=1;i<=m;i++) Add(a[i].x,a[i].y,a[i].z);
Astar();
printf("%d",Ans); }
|