PKU 3259 Wormholes

来源:互联网 发布:java 线程池 消息队列 编辑:程序博客网 时间:2024/06/08 00:12
十分经典的bellman问题,判断负环是否存在,如果存在就可以超越时空了-___-
http://acm.pku.edu.cn/JudgeOnline/problem?id=3259
  1. #include <iostream>
  2. using namespace std;
  3. #define N 2500
  4. #define inf (1<<25)
  5. struct eage
  6. {
  7.   int a,b,len;
  8. }e[3*N];
  9. int d[N+1],pre[N+1];
  10. bool bellman(int s,int n,int t)
  11. {
  12.     int i,j;bool b;
  13.     for(i=1;i<=n;i++)d[i]=inf;
  14.     d[s]=0;//源设置为0
  15.     for(i=1;i<n;i++)
  16.         {
  17.             b=false;
  18.             for(j=0;j<t;j++)//对于每个集合中元素
  19.                 {
  20.                     if(d[e[j].b]>d[e[j].a]+e[j].len)d[e[j].b]=d[e[j].a]+e[j].len,b=true;
  21.                 }
  22.             if(!b)break;
  23.         }
  24.     for(i=0;i<t;i++)
  25.         {//如果找到了负环
  26.             if(d[e[i].b]>d[e[i].a]+e[i].len)return true;
  27.         }
  28.     return false;
  29. }
  30. int main()
  31. {
  32.     int n,t,i,tt,tmp,x,y,len,l;
  33.     cin>>tt;
  34.     while(tt--)
  35.         {
  36.         cin>>n>>t>>tmp;
  37.         l=0;
  38.         for(i=0;i<t;i++)
  39.             {//注意这里是无向图
  40.                 scanf("%d%d%d",&x,&y,&len);
  41.                 e[l].a=x;e[l].b=y;e[l].len=len;
  42.                 l++;
  43.                 e[l].a=y;e[l].b=x;e[l].len=len;
  44.                 l++;
  45.             }
  46.         for(i=0;i<tmp;i++)
  47.             {//注意这里是有向图,边权需要*-1
  48.                 scanf("%d%d%d",&x,&y,&len);
  49.                 len*=-1;
  50.                 e[l].a=x;e[l].b=y;e[l].len=len;
  51.                 l++;
  52.             }
  53.         if(bellman(0,n,l))
  54.             cout<<"YES"<<endl;
  55.         else
  56.             cout<<"NO"<<endl;
  57.     }
  58.     return 0;
  59. }