WormholesPOJ - 3259
耳机楼里有很多教室,这些教室由双向走廊连接。另外,还存在一些单向的秘密通道,通过它们可以回到过去。现在有 N (1 ≤ N ≤ 500) 个教室,编号 1..N, M (1 ≤ M ≤ 2500) 条走廊,和 W (1 ≤ W ≤ 200) 条秘密通道。
DY在养猫之余,还是一个时间旅行爱好者。她希望从一间教室出发,经过一些走廊和秘密通道,回到她出发之前的某个时间。
共有F (1 ≤ F ≤ 5) 组数据。对每组数据,判断DY是否有回到过去的可能性。不存在耗时超过10,000秒的走廊,且不存在能带DY回到10,000秒之前的秘密通道。
首先是一个整数F,表示接下来会有F组数据。
每组数据第1行:分别是三个空格隔开的整数:N,M和W
第2行到M+1行:三个空格分开的数字(S,E,T)描述双向走廊:从S到E需要耗费T秒。两个教室可能由一个以上的路径来连接。
第M +2到M+ W+1行:三个空格分开的数字(S,E,T)描述秘密通道:从S到E可以使时间倒流T秒。
OutputF行,每行对应一组数据。每组数据输出单独的一行,” YES”表示能满足要求,”NO”表示不能满足要求。Sample Input2 3 3 1 1 2 2 1 3 4 2 3 1 3 1 3 3 2 1 1 2 3 2 3 4 3 1 8Sample Output
NO YES
分析:
涉及环的问题,考虑求负环,这里尝试用spfa(队列优化的BF)做的,只要有点进入队列超过n-1次就存在负环,结果因为图没更新,WA了两次。。。变量一多就容易漏啊。。。
代码:
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<string> #include<algorithm> #include<vector> #include<queue> #include<map> #include<stack> #include<set> #include<bitset> #include<list> #define UP(i,x,y) for(int i=x;i<=y;i++) #define DOWN(i,x,y) for(int i=x;i>=y;i--) #define MEM(a,x) memset(a,x,sizeof(a)) #define W(a) while(a) #define ll long long #define INF 0x3f3f3f3f #define EXP 1e-10 #define lowbit(x) (x&-x) using namespace std; int n,m,w; struct edge{ int to,cost; edge(int to,int cost):to(to),cost(cost){} }; vector<edge> G[1510]; int dis[1510],is_join[1510],join_num[1510]; queue<int> q; bool BF(void){ MEM(dis,0x3f); MEM(is_join,0); MEM(join_num,0); while(!q.empty())q.pop(); q.push(1); dis[1]=0; is_join[1]=1; join_num[1]++; while(!q.empty()){ int head=q.front(); q.pop(); is_join[head]=0; for(int i=0;i<G[head].size();i++){ int t=G[head][i].to,c=G[head][i].cost; if(dis[t]>dis[head]+c){ dis[t]=dis[head]+c; if(is_join[t]==0){ q.push(t); is_join[t]=1; join_num[t]++; if(join_num[t]>=n)return 1; } } } /*for(int i=1;i<=n;i++){ cout<<dis[i]<<' '; } cout<<endl;*/ } return 0; } int main(){ int f;cin>>f; while(f--){ cin>>n>>m>>w; for(int i=1;i<=m;i++){ int s,e,t; cin>>s>>e>>t; edge ed1(e,t),ed2(s,t); G[s].push_back(ed1); G[e].push_back(ed2); } for(int i=1;i<=w;i++){ int s,e,t; cin>>s>>e>>t; edge ed(e,t*(-1)); G[s].push_back(ed); } if(BF()) cout<<"YES"<<endl; else cout<<"NO"<<endl; for(int i=1;i<=n;i++){ G[i].clear(); } } return 0; }