POJ 2394 Checking an Alibi(最短路)

来源:互联网 发布:ug8.0编程视频教程全集 编辑:程序博客网 时间:2024/04/20 21:10

题目连接:http://poj.org/problem?id=2394

题意:有F块土地,有的土地上有牛(可能有多头),粮仓在编号为1的土地上,问在M时间内有多少头牛可以到达粮仓,并按升序输出牛的编号。

用SPFA超时了。。。用优先队列优化的Dijkstra,2394Accepted228K0MSC++
代码如下:

#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<queue>using namespace std;#define INS 1<<29#define N 505#define SIZE 2005#define CLR(arr,v) memset(arr,v,sizeof(arr))class short_path{public:short_path(){}void init(int m,int n){num_ed = m;num_v = n;CLR(des,0);CLR(next,0); CLR(h,0);for(int i = 0;i < N;++i)dis[i] = INS;while(!q.empty()) q.pop();}void add(int u,int v,int f){des[++pos] = v;val[pos] = f;next[pos] = h[u];h[u] = pos;}int Dijkstra(int start,vector<int> *end,int limit,bool *cow){dis[start] = 0;mid.d = start;mid.v = 0;q.push(mid);while(!q.empty()){int s = q.top().d,v = q.top().v;q.pop();for(int i = h[s]; i ;i = next[i]){int length = dis[s] + val[i];if(length < dis[ des[i] ] && length <= limit){dis[ des[i] ] = length;mid.d = des[i];mid.v = length;q.push(mid);}}}int sum_cow = 0;for(int i = 1;i <= num_v;++i){if(dis[i] <= limit){for(int j = 0;j < end[i].size();++j){if(!cow[ end[i][j] ]){sum_cow++;cow[ end[i][j] ] = true;}}}}return sum_cow;}private:int h[N],dis[N],des[SIZE],next[SIZE],val[SIZE];int pos,num_ed,num_v,res;struct Edge{int d,v;bool operator<(const Edge &ed) const{return v > ed.v;}};struct Edge mid;priority_queue<Edge> q;};class short_path sp;bool cow[105];vector<int> vec[505];int main(){int F,C,P,M;while(~scanf("%d%d%d%d",&F,&P,&C,&M)){sp.init(P,F);CLR(vec,0);CLR(cow,0);int u,v,c;for(int i = 0;i < P;++i){scanf("%d%d%d",&u,&v,&c);sp.add(u,v,c);sp.add(v,u,c);}for(int i = 1;i <= C;++i){scanf("%d",&c);vec[c].push_back(i);}int cows = sp.Dijkstra(1,vec,M,cow);printf("%d\n",cows);for(int i = 1;i <= C;++i){if(cow[i]) printf("%d\n",i);}}return 0;}



原创粉丝点击