PKU 3259-Wormholes

来源:互联网 发布:淘宝优惠券秒杀代码 编辑:程序博客网 时间:2024/05/29 17:43

用到的算法:Bellman_ford

题目链接:http://poj.org/problem?id=3259

题意:

        John的农场里N块地,M条路连接两块地(双向),w个虫洞,虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts。我们的任务是知道会不会在从某块地出发后又回来,看到了离开之前的自己。

思路:

        由于存在负权边,Dijkstra便不能用了,用Bellman_ford。
        题目简化一下,就是看所给的图中有没有负权回路,如果有的话,输出"YES",否则,输出"NO"。

#include<cstdio>#include<cstring>#define Max 3000struct node{int sta,end,time;void set(int x,int y,int s){sta=x,end=y,time=s;}}edge[2*Max];int dis[Max];bool bellman_ford(int v,int edge_num){memset(dis,0x7f,sizeof(dis));//每个节点到原点的距离都初始化为无穷远dis[1]=0;int i,j;for(i=0;i<v;i++){bool flag=false;for(j=0;j<edge_num;j++){int tx=edge[j].sta,ty=edge[j].end;if(dis[ty]>dis[tx]+edge[j].time)//松弛dis[ty]=dis[tx]+edge[j].time,flag=true;}if(!flag)break;}if(i==v)//如果存在负权回路return true;return false;}int main(){int cas;scanf("%d",&cas);while(cas--){int n,m,w,edge_num=0;scanf("%d %d %d",&n,&m,&w);int x,y,t;while(m--){scanf("%d %d %d",&x,&y,&t);//路是双向的edge[edge_num++].set(x,y,t);edge[edge_num++].set(y,x,t);}while(w--){scanf("%d %d %d",&x,&y,&t);edge[edge_num++].set(x,y,-t);//虫洞的方向的单向的,且时间为负}puts(bellman_ford(n,edge_num)?"YES":"NO");}return 0;}