您的位置:首页 > 其它

POJ 2394 Checking an Alibi(最短路)

2012-04-12 15:21 351 查看
题目连接: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
,dis
,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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: