一、BellmanFord算法

     参考我之前一篇博文:http://www.cnblogs.com/Oloo/articles/3612366.html

     或者《算法导论》第24章单源最短路 bellmanford部分

 二、问题描述

     POJ 3259http://poj.org/problem?id=3259

     有F个农庄。

     对于每个农庄有N块田,有M条路分别连接两块田,这M条路是双向的<第一次没注意到这个条件,导致WA了一次>,有W个虫洞,每个虫洞连接两块田,但是是单向的。

对于每个农场判断,存不存在一个点,从该点出发,经过虫洞和一系列路径可以回到该点,看到以前的出发时候的自己。     

 三、问题分析

     编程之前需要解决两个问题:

     问题一、图的构造

     问题二、目标转换

        

     问题一:这道题目图的构造还是很简单的!以每块田为节点,每条路<包括虫洞>作为边,这样这个图就构造起来了。     

     问题二:图构造好之后,我们很容易发现,这个问题的就是要我们判断图中是否存在负圈,一提到判断图中是否存在负圈,第一时间就可以想到BellmanFord算法。

 四、程序实现

 1 #include<iostream>
 2 using namespace std;
 3 
 4 struct edge
 5 {
 6     int u,v;
 7     int value;
 8 } *edges;
 9 int N; //节点数目
10 int M;//普通边数
11 int W;//虫洞边数
12 int *value;//节点d值
13 
14 void input()
15 {
16     cin>>N>>M>>W;
17     value = new int[(N+1)];
18     for(int i = 0;i < N+1;i++)
19         value[i] = 10001;
20     value[1] = 0;
21     edges = new edge[(2*M+W)];
22     for(int i = 0;i < 2*M;i++)
23     {
24         cin>>edges[i].u>>edges[i].v>>edges[i].value;
25         edges[i+1].u = edges[i].v;
26         edges[i+1].v = edges[i].u;
27         edges[i+1].value = edges[i].value;
28         i++;
29     }
30     for(int i = 2*M;i < W+2*M;i++)
31     {
32         int d = 0;
33         cin>>edges[i].u>>edges[i].v;
34         cin >> d;
35         edges[i].value = -d;
36     }
37 }
38 
39 int Relax(int i)
40 {
41     if(value[edges[i].v] > value[edges[i].u]+edges[i].value)
42     {
43         value[edges[i].v] = value[edges[i].u]+edges[i].value;
44         return 1;
45     }
46     return 0;
47 }
48 
49 int BellmanFord()
50 {
51     int k = 0;
52     while(k < N)
53     {
54         int flag = 0;
55         for(int i = 0;i < 2*M+W;i++)
56             if(Relax(i))
57                 flag = 1;
58         if(!flag) break;
59         k++;
60     }
61     for(int i = 0;i < 2*M+W;i++)
62         if(value[edges[i].v] > value[edges[i].u]+edges[i].value)
63             return 1;
64     return 0;
65 }
66 
67 int main()
68 {
69     int F = 0;//农场数量
70     cin >> F;
71     while(F--)
72     {
73         input();
74         if(BellmanFord()) cout << "YES" <<endl;
75         else cout <<"NO"<<endl;
76     }
77     return 0;
78 }
View Code

 五、感想

       自己通过自己独立分析问题,自己独立编程实现,最后这个题目AC,这个节奏还是很好的~

       最后,YZY,我想你!

 

 

 

 

posted on 2014-03-22 12:48  Oloo  阅读(137)  评论(0)    收藏  举报