首页 > 代码库 > poj 3259 Wormholes 判断负权值回路
poj 3259 Wormholes 判断负权值回路
Wormholes
Time Limit: 2000 MS Memory Limit: 65536 KB
64-bit integer IO format: %I64d , %I64u Java class name: Main
[Submit] [Status] [Discuss]
Description
While exploring his many farms, Farmer John has discovered a number of amazing wormholes. A wormhole is very peculiar because it is a one-way path that delivers you to its destination at a time that is BEFORE you entered the wormhole! Each of FJ‘s farms comprises N (1 ≤ N ≤ 500) fields conveniently numbered 1..N, M (1 ≤ M ≤ 2500) paths, and W (1 ≤ W ≤ 200) wormholes.
As FJ is an avid time-traveling fan, he wants to do the following: start at some field, travel through some paths and wormholes, and return to the starting field a time before his initial departure. Perhaps he will be able to meet himself :) .
To help FJ find out whether this is possible or not, he will supply you with complete maps to F (1 ≤ F ≤ 5) of his farms. No paths will take longer than 10,000 seconds to travel and no wormhole can bring FJ back in time by more than 10,000 seconds.
Input
Output
Sample Input
23 3 11 2 21 3 42 3 13 1 33 2 11 2 32 3 43 1 8
Sample Output
NOYES
Hint
//Memory Time//308K 204MS#include<iostream>#include <string.h>using namespace std;int dis[1001]; //源点到各点权值const int max_w=10001; //无穷远struct weight{ int s; int e; int t;}edge[5200];int N,M,W_h; //N (1≤N≤500)fields 顶点数 //M (1≤M≤2500)paths 正权双向边 //W_h (1≤W≤200) wormholes 虫洞(回溯),负权单向边int all_e; //边集(边总数)bool bellman(){ bool flag; /*relax*/ for(int i=0;i<N-1;i++) ///dis松弛的次数 { flag=false; for(int j=0;j<all_e;j++) ///所有边集 if(dis[edge[j].e] > dis[edge[j].s] + edge[j].t) ///可以松弛 更新 { dis[edge[j].e] = dis[edge[j].s] + edge[j].t; flag=true; //relax对路径有更新 } if(!flag) break; //只要某一次relax没有更新,说明最短路径已经查找完毕,或者部分点不可达,可以跳出relax }///已经更新完毕了 所有边集都是两点之间的最短路 /*Search Negative Circle*/ for(int k=0;k<all_e;k++) ///遍历所有边集 如果还出现能够再次更新成最短的边 就表明出现负权值回路了 if( dis[edge[k].e] > dis[edge[k].s] + edge[k].t) return true; return false;}int main(void){ int u,v,w; int F; cin>>F; while(F--) { memset(dis,max_w,sizeof(dis)); //源点到各点的初始值为无穷,即默认不连通 cin>>N>>M>>W_h; all_e=0; //初始化指针 /*read in Positive Paths*/ for(int i=1;i<=M;i++) { cin>>u>>v>>w; edge[all_e].s=edge[all_e+1].e=u; edge[all_e].e=edge[all_e+1].s=v; edge[all_e++].t=w; edge[all_e++].t=w; //由于paths的双向性,两个方向权值相等,注意指针的移动 } /*read in Negative Wormholds*/ for(int j=1;j<=W_h;j++) { cin>>u>>v>>w; edge[all_e].s=u; edge[all_e].e=v; edge[all_e++].t=-w; //注意权值为负 } /*Bellman-Ford Algorithm*/ if(bellman()) cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0;}//Memory Time//308K 204MS#include<iostream>#include <string.h>using namespace std;int dis[1001]; //源点到各点权值const int max_w=10001; //无穷远struct weight{ int s; int e; int t;}edge[5200];int N,M,W_h; //N (1≤N≤500)fields 顶点数 //M (1≤M≤2500)paths 正权双向边 //W_h (1≤W≤200) wormholes 虫洞(回溯),负权单向边int all_e; //边集(边总数)bool bellman(){ bool flag; /*relax*/ for(int i=0;i<N-1;i++) ///dis松弛的次数 { flag=false; for(int j=0;j<all_e;j++) ///所有边集 if(dis[edge[j].e] > dis[edge[j].s] + edge[j].t) ///可以松弛 更新 { dis[edge[j].e] = dis[edge[j].s] + edge[j].t; flag=true; //relax对路径有更新 } if(!flag) break; //只要某一次relax没有更新,说明最短路径已经查找完毕,或者部分点不可达,可以跳出relax }///已经更新完毕了 所有边集都是两点之间的最短路 /*Search Negative Circle*/ for(int k=0;k<all_e;k++) ///遍历所有边集 如果还出现能够再次更新成最短的边 就表明出现负权值回路了 if( dis[edge[k].e] > dis[edge[k].s] + edge[k].t) return true; return false;}int main(void){ int u,v,w; int F; cin>>F; while(F--) { memset(dis,max_w,sizeof(dis)); //源点到各点的初始值为无穷,即默认不连通 cin>>N>>M>>W_h; all_e=0; //初始化指针 /*read in Positive Paths*/ for(int i=1;i<=M;i++) { cin>>u>>v>>w; edge[all_e].s=edge[all_e+1].e=u; edge[all_e].e=edge[all_e+1].s=v; edge[all_e++].t=w; edge[all_e++].t=w; //由于paths的双向性,两个方向权值相等,注意指针的移动 } /*read in Negative Wormholds*/ for(int j=1;j<=W_h;j++) { cin>>u>>v>>w; edge[all_e].s=u; edge[all_e].e=v; edge[all_e++].t=-w; //注意权值为负 } /*Bellman-Ford Algorithm*/ if(bellman()) cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0;}
poj 3259 Wormholes 判断负权值回路