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 }
View Code

 

 

posted on 2013-09-09 11:24  码农之上~  阅读(158)  评论(0编辑  收藏  举报

导航