题目大意:利用虫洞的时光旅行,若能回到过去,则输出"YES",否则"NO"。
给定F(1<=F<=5)组数据,对应与一个farm,每组数据对应一个结果。
对于其中一组数据,给定 N , M , W ,N为点数,M为无向边数(普通路径,通过之后时间前进),W为有向边数(虫洞,通过虫洞之后时间倒退),求每组数据是否存在一条回路能使时间倒退。
解题思路:若存在这样一条回路,则图中肯定存在负环。只要判断是否有负环就行了。
AC Code (1): bellmanFord Memory: 236K Time: 141Ms
#include <iostream>
#include <cstdio>
#include <cstring>
#define Inf 0x7fffffff
#define MaxV 501
#define MaxE 6000
using namespace std;
int F,N,M,W;
struct Edge { int to,next,time; }edge[MaxE];
int size,head[MaxE];
void InsertEdge(int from,int to,int time)
{edge[size].to=to; edge[size].time=time;
edge[size].next=head[from]; head[from]=size++;
}
int dist[MaxV];
bool bellmanFord()
{bool flag; int i,j,k,to;
memset(dist,Inf,sizeof(dist));
dist[1]=0;
for(i=1;i<=N-1;i++)
{ flag=false;
for(j=1;j<=N;j++)
{ for(k=head[j];k+1;k=edge[k].next)
{ to=edge[k].to;
if(dist[to]>dist[j]+edge[k].time)
{ flag=true; dist[to]=dist[j]+edge[k].time; }
}
}
if(!flag) break;
}
for(j=1;j<=N;j++)
{ for(k=head[j];k+1;k=edge[k].next)
{ to=edge[k].to; if(dist[to]>dist[j]+edge[k].time) return false; }
}
return true;
}
void init()
{ int i; int from,to,time;
scanf("%d%d%d",&N,&M,&W);
size=0; memset(head,-1,sizeof(head));
for(i=0;i<M;i++)
{ scanf("%d%d%d",&from,&to,&time);
InsertEdge(from,to,time);InsertEdge(to,from,time);
}
for(i=0;i<W;i++)
{ scanf("%d%d%d",&from,&to,&time); InsertEdge(from,to,0-time); }
}
int main()
{ //freopen("in.txt","r",stdin);
scanf("%d",&F);
while(F--)
{ init();
if(bellmanFord()) printf("NO\n");
else printf("YES\n");
}
return 0;
}
AC Code
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define Inf 0x7fffffff
#define MaxV 501
#define MaxE 6000
using namespace std;
int F,N,M,W;
struct Edge{ int to,next,time; }edge[MaxE];
int size,head[MaxE];
void InsertEdge(int from,int to,int time)
{ edge[size].to=to; edge[size].time=time;
edge[size].next=head[from]; head[from]=size++;
}
int dist[MaxV]; int cot[MaxV]; bool vst[MaxV];
bool spfa()
{ queue<int> que; int i,from,to;
for(i=0;i<=N;i++) dist[i]=Inf; //这里用 memset出错
memset(vst , 0 ,sizeof( vst));
memset(cot , 0 ,sizeof( cot));
dist[1]=0,vst[1]=1; que.push(1);
while(!que.empty())
{ from=que.front(),vst[from]=0,que.pop(); cot[from]++;
if(cot[from]>=N) return false;
for(i=head[from];i+1;i=edge[i].next)
{ to=edge[i].to;
if(dist[to]>dist[from]+edge[i].time)
{ dist[to]=dist[from]+edge[i].time;
if(!vst[to])
que.push(to),vst[to]=1;
}
}
}
return true;
}
void init()
{ int i; int from,to,time;
scanf("%d%d%d",&N,&M,&W);
size=0; memset(head,-1,sizeof(head));
for(i=0;i<M;i++)
{ scanf("%d%d%d",&from,&to,&time);
InsertEdge(from,to,time);InsertEdge(to,from,time);
}
for(i=0;i<W;i++)
{ scanf("%d%d%d",&from,&to,&time);
InsertEdge(from,to,0-time);
}
}
int main()
{ scanf("%d",&F);
while(F--)
{ init();
if(spfa()) printf("NO\n");
else printf("YES\n");
}
return 0;
}