POJ 3259题

题意 : 一个famer有一些农场,这些农场里面有一些田地,田地里面有一些虫洞,田地和田地之间有路,虫洞有这样的性质: 时间倒流。问你这个农民能不能看到他自己,也就是说,有没有这样一条路径,能利用虫洞的时间倒流的性质,让这个人能在这个点出发前回去,这样他就是能看到他自己
解题思路:使用Bellman-Ford算法,看图中有没有负权环。有的话就是可以,没有的话就是不可以了。
#include <stdio.h>
#define arraysize 5500
#define array 501
//int maxData = 0x7fffffff;
int maxData =10001; //切记:此处设置为10001,否则会一直提交出错,不要设置成无穷大
struct node
{
 int v;   //起点 
 int u;   //终点
 int w;
}edges[arraysize]; //存储边
int d[array];  //存储最短路径
int n,m,w;
bool bellman_ford()
{
 for(int i=1;i<n+1;i++) //初始化最短路径,全部设置为无穷大
 {
  d[i] = maxData;
 }
 d[1] = 0;    //将源点的距离设置为0
 for(int i1=1;i1<n;++i1) //对每一条边进行|V(G)|-1次遍历,并进行松弛操作
 {
  for(int i2=1;i2<2*m+w+1;++i2) //边的总数为2*m+w+1
  {
   if(d[edges[i2].u]>d[edges[i2].v]+edges[i2].w) //注:此处u是终点
   {
    d[edges[i2].u] = d[edges[i2].v] + edges[i2].w;
   }
  }
 }
 for(int i3=1;i3<2*m+w+1;++i3) //对所有的边进行检查,判断是否出现负权回路
 {
  if(d[edges[i3].u]>d[edges[i3].v]+edges[i3].w)
   return false;
 }
 return true;
}
int main()
{
 //freopen("1.txt","r",stdin);
 int f;
 scanf("%d",&f);
 for(int i=0;i<f;++i)
 {
  scanf("%d%d%d",&n,&m,&w);
  int size = 0;    
  for(int i1=0;i1<m;++i1)  //两块地之间的路径是双向路径
  {
   size++;
   scanf("%d%d%d",&edges[size].v,&edges[size].u,&edges[size].w);
   size++;
   edges[size].v = edges[size-1].u;
   edges[size].u = edges[size-1].v;
   edges[size].w = edges[size-1].w;
  }
  for(int i2=0;i2<w;++i2)  //虫洞的路径是单向路径
  {
   size++;
   scanf("%d%d%d",&edges[size].v,&edges[size].u,&edges[size].w);
   edges[size].w = -edges[size].w;
  }
  if(bellman_ford())
   printf("NO\n");
  else
   printf("YES\n");
 }

 return 0;
}

你可能感兴趣的:(poj)