题意:一个famer有一些农场,这些农场里面有一些田地,田地里面有一些虫洞,田地和田地之间有路(双向的),即从a到b和从b到a时间都为c.虫洞的性质:时间倒流。即通过虫洞从a到b所花时间为 -c(单向的).问从某块田出发,他能否通过虫洞的性质回到出发点前
思路:这题实际就是判断是否存在负权回路,可以用SPFA算法或Bellman-Ford算法判断。若存在负权回路,则可以达到目的,否则不可以。
Bellman-ford算法
#include<stdio.h>
#include<limits.h>
struct stu
{
int a,b,c;
}edge[6000];
int dis[550],n,m;
int bellmanford()
{
int flag=0,i,j;
for(i=1;i<=n;i++)
dis[i]=INT_MAX;
dis[1]=0;
for(i=1;i<=n-1;i++)
for(j=1;j<=m;j++)
if(dis[edge[j].a]!=INT_MAX&&dis[edge[j].a]+edge[j].c<dis[edge[j].b])
dis[edge[j].b]=dis[edge[j].a]+edge[j].c;
for(i=1;i<=m;i++) //判断负权回路
if(dis[edge[i].a]!=INT_MAX&&dis[edge[i].a]+edge[i].c<dis[edge[i].b]){
flag=1;
break;
}
return flag;
}
int main()
{
int T,i,j,k,flag;
scanf("%d",&T);
while(T--){
scanf("%d%d%d",&n,&m,&k);
j=1;
for(i=1;i<=m;i++){
scanf("%d%d%d",&edge[j].a,&edge[j].b,&edge[j].c);
j++;
edge[j].a=edge[j-1].b; //路是双向的
edge[j].b=edge[j-1].a;
edge[j].c=edge[j-1].c;
j++;
}
for(i=1;i<=k;i++){
scanf("%d%d%d",&edge[j].a,&edge[j].b,&edge[j].c);
edge[j].c=-edge[j].c; //虫洞是单向的,时间为负
j++;
}
m=j-1;
flag=bellmanford();
if(flag)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}