Wormholes
题目描述
教学楼里有很多教室,这些教室由双向走廊连接。另外,还存在一些单向的秘密通道,通过它们可以回到过去。现在有 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秒。
输出格式
F行,每行对应一组数据。 每组数据输出单独的一行,” YES”表示能满足要求,”NO”表示不能满足要求。
输入样例
2 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 8
输出样例
NO YES
题目链接
https://vjudge.net/problem/POJ-3259
题目的要求是回到她出发之前的某个时间,即从i再次走到i时,所用时间为负数,Floyd算法算出每两个教室的时间,再判断一下从i再次走到i时的所用时间是否<0即可
AC代码
#include <iostream> #include <cstdio> #include <fstream> #include <algorithm> #include <cmath> #include <deque> #include <vector> #include <queue> #include <string>1 #include <cstring> #include <map> #include <stack> #include <set> #include <sstream> #define IOS ios_base::sync_with_stdio(0); cin.tie(0) #define Mod 1000000007 #define eps 1e-6 #define ll long long #define INF 0x3f3f3f3f #define MEM(x,y) memset(x,y,sizeof(x)) #define Maxn 500+5 #define P pair<int,int> using namespace std; int N,M,W; int S,E,T; int d[Maxn][Maxn]; void init() { //i到j的距离为INF MEM(d,INF); for(int i=1; i<=N; i++)//自己到自己的距离为0 d[i][i]=0; } bool Floyd()//Floyd算法求最短路 { int i,j,k; for(k=1; k<=N; k++) { for(i=1; i<=N; i++) { for(j=1; j<=N; j++) { if(d[i][j]>d[i][k]+d[k][j])//(用min会超时) d[i][j]=d[i][k]+d[k][j]; } if(d[i][i]<0)//转了一圈,回到这里时,时间为负数,则回到她出发之前的某个时间 return 1; } } return 0; } int main() { IOS; int F; cin>>F; while(F--) { cin>>N>>M>>W; init(); for(int i=0; i<M; i++) { int x,y,z; cin>>x>>y>>z; if(z<d[x][y]) d[x][y]=d[y][x]=z;//走廊双向 } for(int i=0; i<W; i++) { int x,y,z; cin>>x>>y>>z; d[x][y]=-z;//秘密通道单=向 } if(Floyd()) cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0; }