POJ 3259 Wormholes
这道题也学到了不少东西。
题目链接:http://poj.org/problem?id=3259
题意就是一块地上有n个区域,m条路径,有w个虫洞,要你求能不能从某个区域开始然后经过某种路径,最后回到该区域,而此时的时间在离开的时间之前。
明显的Bellman,可是如何处理呢?
好吧,既然题意是说从某个区域,意思是图中只要有负环就可以了,而只要有负环那么Bellman算法中的n-1次松弛就必然能完成。
所以关键在于检验是否能进行n-1次松弛。
上代码
1 #include<stdio.h> 2 #define repA(p,q,i) for( int (i)=(p); (i)!=(q); ++(i) ) 3 #define repAE(p,q,i) for( int (i)=(p); (i)<=(q); ++(i) ) 4 #define repD(p,q,i) for( int (i)=(p); (i)!=(q); --(i) ) 5 #define repDE(p,q,i) for( int (i)=(p); (i)>=(q); --(i) ) 6 7 #define VMAX 520 8 #define EMAX 5500 9 #define MAXN 0x3f3f3f3f 10 struct node{ 11 int f,t,c; 12 node(){} 13 node( int _f , int _t , int _c ) 14 : f(_f) , t(_t) , c(_c) {} 15 }; 16 17 node fun[EMAX]; 18 int dis[VMAX]; 19 int F,N,M,W,S,E,T; 20 int order; 21 bool Bellman(); 22 23 int main() 24 { 25 scanf("%d",&F); 26 while(F--) 27 { 28 order=0; 29 scanf("%d%d%d",&N,&M,&W); 30 repA(0,M,i) 31 { 32 scanf("%d%d%d",&S,&E,&T); 33 fun[order++] = node(S,E,T) ; 34 fun[order++] = node(E,S,T) ; 35 } 36 repA(0,W,i) 37 { 38 scanf("%d%d%d",&S,&E,&T); 39 fun[order++] = node(S,E,-T) ; 40 } 41 printf("%s\n", Bellman()==true ? "YES":"NO" ) ; 42 } 43 return 0; 44 } 45 46 bool Bellman() 47 { 48 repA(0,VMAX,i) 49 dis[i] = MAXN ; 50 dis[1]=0; 51 bool flag; 52 int i,temp; 53 for(i=1; i!=N; ++i) 54 { 55 flag = false ; 56 repA(0,order,j) 57 { 58 temp = dis[ fun[j].f ] + fun[j].c ; 59 if( temp < dis[ fun[j].t ] ) 60 { dis[ fun[j].t ] = temp ; 61 flag = true ; } 62 } 63 if( ! flag ) break ; 64 } 65 return i == N ; 66 }
To Be The Best Of Yourself