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

来源:互联网 发布:鞍山北国知春67价格 编辑:程序博客网 时间:2024/05/30 19:33

题目传送门:【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;}
原创粉丝点击