题目链接:http://poj.org/problem?id=3259
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
Hint
For farm 1, FJ cannot travel back in time.
For farm 2, FJ could travel back in time by the cycle 1->2->3->1, arriving back at his starting location 1 second before he leaves. He could start from anywhere on the cycle to accomplish this.
题目大意:给出一个混合图(无向图+有向图),无向图事路,有向图是虫洞,虫洞可以回到过去;
如果能回到过去(经过虫洞后原点时间减少了)能则输出yes,否则输出no
大佬们有好多fang方法判断负环,但是我目前只会一种QAQ。。
spfa模板判断fu'h负环,
首先输入该地图,然后从一个点开始查找最短路,之后就是套用spfa模板了,有负环的存在返回1,无返回0;
对于模板,分为三个步骤
初始化:首先初始化数组shuaxin(用来记录最短路)为INF,biaoji(用于标记是否在队列)为0(不在),num(记录某一点进入队列的次数)为0;
起点入列:
循环判断:取出队首元素,取消标记(不在队列),利用邻接矩阵刷新最短距离,对于没有入列但可以入列de的的点,入列,标记,判断是否该点重复使用n次,ru'g如果重复使用,说明有fu'h负环,返回1;如果走完全程仍没有重复次数>n的,则代表代表没有负环。
#include<stdio.h>
#include<string.h>
#include<math.h>
//#include<map>
//#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
#define clean(a,b) memset(a,b,sizeof(a))// 水印
#define mod 1000000
int shuzu[510][510];
int shuaxin[510],num[510];
bool biaoji[510];
int n,m,w;
int spfa(int x)
{
clean(biaoji,0);
clean(num,0);
clean(shuaxin,INF);
queue<int> que;
while(que.size())
que.pop();
//初始化完成
biaoji[x]=1;
shuaxin[x]=0;
num[x]=1;
que.push(x);
//起点入列
while(que.size())
{
int can=que.front();//以改点为起点判断 刷新
que.pop();
biaoji[can]=0;
for(int i=1;i<=n;++i)
{
if(shuaxin[can]+shuzu[can][i]<shuaxin[i])
{
shuaxin[i]=shuzu[can][i]+shuaxin[can];//刷新
if(biaoji[i]==0)//判断 改点是否在队列
{
biaoji[i]=1;
num[i]++;//重复++
if(num[i]>n)
return 1;//有负环
que.push(i);
}
}
}
}
return 0;
}
int main()
{
int t;
cin>>t;
while(t--)
{
clean(shuzu,INF);
cin>>n>>m>>w;
for(int i=0;i<m;++i)
{
int s,e,l;
cin>>s>>e>>l;
if(shuzu[s][e]>l)
{
shuzu[s][e]=l;
shuzu[e][s]=l;
}
}
for(int i=0;i<w;++i)
{
int s,e,l;
cin>>s>>e>>l;
shuzu[s][e]=-l;//虫洞
}
if(spfa(1))
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
}