您的位置:首页 > 其它

[POJ 3259] Wormholes 最短路判负环(SPFA版)

2017-06-24 13:18 302 查看
题目传送门:【POJ 3259】

题目大意: John 有许多农场,每一个农场可以被看作是一个无向图,农场上有许多虫洞,这些虫洞连接着一些点,并且是有向的。每个虫洞可以使 John 回溯一段时间。John 想通过虫洞回到过去,因此他需要穿越农场中的一些边来到达虫洞。求最后他能否回到过去:-)

题目分析:

一道入门的最短路问题。

根据求最短路的性质,当图中有负环时,最短路不存在(或者是无穷小)。这里,如果把虫洞看作负值,那么有负环的时候,John 可以回溯到之前的任意时刻,当然也可以回到出发点。所以仅需判断有无负环即可。

这里我用的 SPFA 来判断,其他的例如 Floyd 也可以做。

下面附上代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
const int MX=10005;

int head[MX];
struct Edge{
int len,to,next;
};
Edge edge[MX];
int n,m,w,now = 0;

void adde(int u,int v,int len){
edge[++now].to = v;
edge[now].len = len;
edge[now].next = head[u];
head[u] = now;
}
bool spfa(int s){
queue<int> q;
int dis[MX],cnt[MX] = {0};
bool vis[MX] = {0};
memset(dis,0x3f,sizeof(dis));
dis[s] = 0;
vis[s] = true;
q.push(s);
while (!q.empty()){
int u = q.front();
q.pop();
for (int i = head[u]; i ;i = edge[i].next){
int v = edge[i].to;
if (dis[u] + edge[i].len < dis[v]){
dis[v] = dis[u] + edge[i].len;
cnt[v]++;
q.push(v);
if (cnt[v] >= n) return true;
}
}
}
return false;
}
void init(){
memset(head,0,sizeof(head));
memset(edge,0,sizeof(edge));
now = 0;
}
int main(){
int F;
cin>>F;
while (F--){
init();
cin>>n>>m>>w;
int a,b,l;
for (int i = 1;i <= m;i++){
cin>>a>>b>>l;
adde(a,b,l);
adde(b,a,l);
}
for (int i = 1;i <= w;i++){
cin>>a>>b>>l;
adde(a,b,-l);
}
if (spfa(1)) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: