这道题是一个农场有F个神奇的农场
农场有N个点,M条路,W个虫洞。虫洞能回溯时间。
问能不能从某个点出发,通过路和虫洞,回到原点,时间比原来早。
我第一思路是用bellman-ford算法,可以求是否出现负权值情况来做。
提交了好几次不对,发现坑爹之处是M条路是双向的,W个虫洞是单向的,理解了这个以后就能做了。它是要求某个点,所以要便利所有点来做bellman算法。
#include <cstring>
#include <cstdio>
#define INF 0x3f3f3f3f
using namespace std;
struct edge
{
int from,to,cost;
edge(int f,int t,int c):from(f),to(t),cost(c){};
edge(){}
};
edge es[3000];
int d[550];
int F,N,M,W;
void bellman(){
for (int k = 1; k <= N; ++k)
{
memset(d,INF,sizeof(d));
d[k]=0;
int flag=1;
while(flag){
flag=0;
for (int i = 0; i < M+W; ++i)
{
edge e=es[i];
if (d[e.from]!=INF&&d[e.from]+e.cost<d[e.to]&&d[e.to]>=0)
{
d[e.to]=d[e.from]+e.cost;
flag=1;
}
if (i<M&&d[e.to]!=INF&&d[e.to]+e.cost<d[e.from]&&d[e.from]>=0)
{
d[e.from]=d[e.to]+e.cost;
flag=1;
}
}
}
if (d[k]<0){
printf("YES\n");
return ;
}
}
printf("NO\n");
}
int main(int argc, char const *argv[])
{
scanf("%d",&F);
int x,y,w;
while(F--){
scanf("%d%d%d",&N,&M,&W);
int i;
for ( i = 0; i < M; ++i)
{
scanf("%d%d%d",&x,&y,&w);
es[i].from=x;
es[i].to=y;
es[i].cost=w;
}
for (; i <M+W; ++i)
{
scanf("%d%d%d",&x,&y,&w);
es[i].from=x;
es[i].to=y;
es[i].cost=-w;
}
bellman();
}
return 0;
}
原文:http://blog.csdn.net/ysgcreate/article/details/44631059