1.首先解读一下以下原文:第一行要输入case的组数,接下来每组数据的第一行输入分别输入三个数N,M,W,第2到M+1行输入双向的路径S,E,T,第M+2到M+W行输入单向的路径S,E,T(即虫洞,普通path是加时间,wormhole是减时间)。下一组数据重复上述步骤。
Line 1: A single integer F.
F farm descriptions follow.
Line 1 of each farm: Three space-separated integers respectively: N , M , and WLines 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.
2.又给poj贡献了三个WA,起初看discuss有人说是数组不够大的原因,事实上只要按照题目要求设数组就好了。
3.这里用的是bellman-ford算法,源点是1,和poj1860不同的地方在于除源点以外的顶点初始值都必须取max,因为我们要找出负权环,即存在至少一个顶点的值可以不断减少。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int max=10010;
int fields[505];
int n,m,w,p;
struct paths
{
int start;
int end;
int time;
}path[5500];
bool each_travel(int i)
{
int t=fields[path[i].start]+path[i].time;
if(t<fields[path[i].end])
{
fields[path[i].end]=t;
//cout<<t;
return true;
}
return false;
}
bool travel()
{
int i;
bool flag;
do
{
flag=false;
for(i=1;i<=2*m+w;i++)
{
if(each_travel(i))
flag=true;
}
if(fields[1]<0)
{
return true;
}
}while(flag);
return false;
}
int main()
{
//freopen("D:/input.txt","r",stdin);
//freopen("D:/output.txt","w",stdout);
bool back;
int f;
int s,e,t;
int i;
cin>>f;
while(f--)
{
p=1;
memset(fields,max,sizeof(fields));
fields[1]=0;
cin>>n>>m>>w;
for(i=0;i<m;i++)
{
cin>>s>>e>>t;
path[p].start=s;
path[p].end=e;
path[p++].time=t;
path[p].start=e;
path[p].end=s;
path[p++].time=t;
}
for(i=0;i<w;i++)
{
cin>>s>>e>>t;
path[p].start=s;
path[p].end=e;
path[p++].time=-t; //注意虫洞的时间是负值,这里先前没有改为p++,wa了几次
}
back=travel();
if(back)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}