pku2914 Minimum Cut 无向图最小割 Stoer_Wagner算法

题目不用描述了,很裸,求一个无向图的最小割。
用网络流+枚举这题肯定TLE,学到一个新算法,贴代码,大家可以作为模板
  1 #include <cmath>
  2 
  3 #include <cstdio>
  4 
  5 #include <memory.h>
  6 
  7 #include <algorithm>
  8 
  9 #include <iomanip>
 10 
 11 #include <iostream>
 12 
 13 #include <vector>
 14 
 15 #include <string>
 16 
 17 #include <queue>
 18 
 19  
 20 
 21 using namespace std;
 22 
 23  
 24 
 25 const int N = 500 + 3;
 26 
 27  
 28 
 29 int n, m;
 30 
 31 int mat[N][N];
 32 
 33 int dist[N];
 34 
 35 int visited[N];
 36 
 37 int del[N];  // true表示该点已经被删掉
 38 
 39  
 40 
 41 // 结点~n
 42 
 43 int Stoer_Wagner()
 44 
 45 {
 46 
 47      int minCut = INT_MAX;  // 无向图最小割
 48 
 49      int tmp;
 50 
 51      int i, t, j, k, pre;
 52 
 53      int s = 1;   // 源点
 54 
 55      memset(del, 0sizeof(del));
 56 
 57  
 58 
 59      for (t = 1; t < n; t++)  // n - 1次Maximum Adjacency Search
 60 
 61      {
 62 
 63          for (i = 1; i <= n; i++)
 64 
 65               if (!del[i])
 66 
 67                    dist[i] = mat[s][i];
 68 
 69  
 70 
 71          memset(visited, 0sizeof(visited));
 72 
 73          visited[s] = 1;
 74 
 75          k = s;
 76 
 77          for (i = 1; i <= n - t; i++)  // 每次剩下n - t + 1个结点
 78 
 79          {
 80 
 81               tmp = -1e9;
 82 
 83               pre = k;
 84 
 85               k = 0;
 86 
 87               for (j = 1; j <= n; j++)
 88 
 89               {
 90 
 91                    if (!del[j] && !visited[j] && dist[j] > tmp)
 92 
 93                    {
 94 
 95                        k = j;
 96 
 97                        tmp = dist[j];
 98 
 99                    }
100 
101               }
102 
103               if (!k) return 0;  // 不连通
104 
105  
106 
107               visited[k] = 1;
108 
109               for (j = 1; j <= n; j++)
110 
111                    if (!del[j] && !visited[j])
112 
113                        dist[j] += mat[k][j];
114 
115          }
116 
117  
118 
119          minCut = min(minCut, dist[k]);
120 
121          del[k] = 1;  // 删除k点
122 
123  
124 
125          // 合并k点和源点
126 
127          
128 
129          for (i = 1; i <= n; i++)
130 
131               if (!del[i] && i != pre)
132 
133               {
134 
135                    mat[pre][i] += mat[k][i];
136 
137                    mat[i][pre] = mat[pre][i];
138 
139               }
140 
141      }
142 
143  
144 
145      return minCut;
146 
147 }
148 
149  
150 
151 int main ()
152 
153 {
154 
155      int u, v, w, i;
156 
157      while (scanf("%d%d"&n, &m) != EOF)
158 
159      {
160 
161          memset(mat, 0sizeof(mat));
162 
163          while (m--)
164 
165          {
166 
167               scanf("%d%d%d"&u, &v, &w);
168 
169               if (u == v) continue;  
170 
171               mat[u + 1][v + 1+= w;
172 
173               mat[v + 1][u + 1+= w;
174 
175          }
176 
177          printf("%d\n", Stoer_Wagner());
178 
179      }
180 
181 }
182 
183 


posted on 2010-10-25 23:42 yzhw 阅读(417) 评论(0)  编辑 收藏 引用 所属分类: graph


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2010年11月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

导航

统计

公告

统计系统

留言簿(1)

随笔分类(227)

文章分类(2)

OJ

最新随笔

搜索

积分与排名

最新评论

阅读排行榜