Wormholes
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 61417 | Accepted: 22899 |
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
Line 1: A single integer, F. F farm descriptions follow.
Line 1 of each farm: Three space-separated integers respectively: N, M, and W
Lines 2..M+1 of each farm: Three space-separated numbers (S, E, T) that describe, respectively: a bidirectional path between S and E that requires T seconds to traverse. Two fields might be connected by more than one path.
Lines M+2..M+W+1 of each farm: Three space-separated numbers (S, E, T) that describe, respectively: A one way path from S to E that also moves the traveler back T seconds.
Output
Lines 1..F: For each farm, output "YES" if FJ can achieve his goal, otherwise output "NO" (do not include the quotes).
Sample Input
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
Sample Output
NO YES
题意:输入 t 表示 t 组数据
n 个农场有 m 条路(路双向的),还有 w 条虫洞(虫洞单向的),虫洞可以穿越到过去
然后给出的 m 条路的数据和 w 条虫洞的数据
问他能不能看见之前的自己
思路:虫洞就是一个负值,路是正值,所以可以用SPFA算法来求, 只要有负环就可以了
坑点:无
AC代码:
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn=5100;
const int INF=0x7f7f7f7f;
int map[maxn][maxn],dis[maxn],ans[maxn];
int n,m,w;
bool vis[maxn];
int SPFA(int x)
{
memset(vis,false,sizeof(vis));
memset(ans,0,sizeof(ans));
int now,end,i;
queue<int> q;
while (!q.empty())
q.pop();
q.push(x);
vis[x]=true;dis[x]=0;
ans[x]=1;
while (q.size())
{
now=q.front();
q.pop();
vis[now]=false;
for (i=1;i<=n;i++)
{
if (map[now][i]==INF||dis[now]==INF)
continue;
if (dis[i]>dis[now]+map[now][i])
{
dis[i]=dis[now]+map[now][i];
ans[i]++; //用来记录 i 被改变的次数,如果存在负值的情况会一直改变
if (vis[i]==false)
{
vis[i]=true;
q.push(i);
}
if (ans[i]>n) //当改变的次数超过 n 次的时候,可以判断有负环的存在
return 1;
}
// cout<<dis[i]<<endl;
}
}
return 0;
}
int main()
{
int t,i,j,ans;
int beg,end,l;
cin>>t;
while (t--)
{
cin>>n>>m>>w;
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
map[i][j]=INF;
for (i=1;i<=n;i++)
map[i][i]=0;
for (i=1;i<=n;i++)
dis[i]=INF;
for (i=1;i<=m;i++)
{
cin>>beg>>end>>l;
if (map[beg][end]>l)
{
map[beg][end]=map[end][beg]=l;
}
}
for (i=1;i<=w;i++)
{
cin>>beg>>end>>l;
if (map[beg][end]>-l)
map[beg][end]=-l;
}
ans=SPFA(1);
if (ans==1)
cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
至今还不知道我之前怎么超内存的.....