hdu3691Nubulsa Expo(Stoer-Wagner求无向图全局最小割)
2013-10-04 17:57
435 查看
题目请戳这里
题目大意:给一张图,n个点,m条无向边,每条边有权值,表示该路人流量上界。给定起点s,问如何选终点t,能是s-t的所有路径上最小人流量总和最大,给出这个最大流量。
题目分析:根据最大流最小割定理,此题就是求一个最小割。给定的起点是无用信息,因为起点一定在某个割集中,那么终点在另一个割集随便找一点即可。所以此题求的是一个全局最小割。最大流可以解决。但需要O(n)枚举终点。再加上最大流的复杂度,至少要O(n^4),对于此题来说复杂度偏高,所以要找其他算法。
Stoer-Wagner算法是求无向图全局最小割的一个有效算法,最坏时间复杂度O(n^3),主要思想是先找任意2点的最小割,然后记录下这个最小割,再合并这2个点。这样经过n-1次寻找任意2点最小割,每次更新全局最小割,最后整张图缩成一个点,算法结束,所保存下来的最小割就是全局最小割。
Stoer-Wagner的正确性:
设s和t是图G的2个顶点,图G的全局最小割要么是s-t的最小割,此时s和t在G的全局最小割的2个不同的子集中,或者是G中将s和t合并得的的新图G'的全局最小割,此时s和t在G的全局最小割的同一个子集中。所以只需要不断求出当前图中任意2个点的最小割,然后合并这2个点。不断缩小图的规模求得最小割。
关于更详细的Stoer-Wagner算法:
1:这是英文版论文,英语太烂,没勇气看,不过里面有个插图蛮好的,可以很直观的体会这个算法的工作过程。
2:这篇给了一点证明
3:看看吧
详情请见代码:
题目大意:给一张图,n个点,m条无向边,每条边有权值,表示该路人流量上界。给定起点s,问如何选终点t,能是s-t的所有路径上最小人流量总和最大,给出这个最大流量。
题目分析:根据最大流最小割定理,此题就是求一个最小割。给定的起点是无用信息,因为起点一定在某个割集中,那么终点在另一个割集随便找一点即可。所以此题求的是一个全局最小割。最大流可以解决。但需要O(n)枚举终点。再加上最大流的复杂度,至少要O(n^4),对于此题来说复杂度偏高,所以要找其他算法。
Stoer-Wagner算法是求无向图全局最小割的一个有效算法,最坏时间复杂度O(n^3),主要思想是先找任意2点的最小割,然后记录下这个最小割,再合并这2个点。这样经过n-1次寻找任意2点最小割,每次更新全局最小割,最后整张图缩成一个点,算法结束,所保存下来的最小割就是全局最小割。
Stoer-Wagner的正确性:
设s和t是图G的2个顶点,图G的全局最小割要么是s-t的最小割,此时s和t在G的全局最小割的2个不同的子集中,或者是G中将s和t合并得的的新图G'的全局最小割,此时s和t在G的全局最小割的同一个子集中。所以只需要不断求出当前图中任意2个点的最小割,然后合并这2个点。不断缩小图的规模求得最小割。
关于更详细的Stoer-Wagner算法:
1:这是英文版论文,英语太烂,没勇气看,不过里面有个插图蛮好的,可以很直观的体会这个算法的工作过程。
2:这篇给了一点证明
3:看看吧
详情请见代码:
#include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N = 305; const int M = 50005; const int inf = 0x3f3f3f3f; int g ,v ,dis ; bool vis ; int m,n,s; void build() { int a,b,c; memset(g,0,sizeof(g)); while(m --) { scanf("%d%d%d",&a,&b,&c); g[a][b] += c; g[b][a] += c; } } void solve() { int i,j; int ans = inf; int maxx,maxi; int s,t; for(i = 1;i <= n;i ++) v[i] = i;//初始化点集 while(n > 1) { int cur,pre; cur = 1; memset(dis,0,sizeof(dis)); memset(vis,false,sizeof(vis)); for(i = 2;i <= n;i ++) { dis[v[i]] = g[v[1]][v[i]]; } vis[v[1]] = true; for(i = 1;i < n;i ++) { maxx = -1; maxi = 0; for(j = 1;j <= n;j ++) { if(vis[v[j]] == false && maxx < dis[v[j]]) { maxx = dis[v[j]];//找离当前集合最远的点 maxi = j; } } vis[v[maxi]] = true; if(i == n - 2) s = maxi; if(i == n - 1) t = maxi; for(j = 1;j <= n;j ++) { if(vis[v[j]] == false) dis[v[j]] += g[v[maxi]][v[j]]; } } ans = min(ans,dis[v[t]]); for(i = 1;i <= n;i ++) { g[v[s]][v[i]] += g[v[t]][v[i]]; g[v[i]][v[s]] = g[v[s]][v[i]]; } v[maxi] = v ; n --; } printf("%d\n",ans); } int main() { while(scanf("%d%d%d",&n,&m,&s),n) { build(); solve(); } return 0; }
相关文章推荐
- Stoer-Wagner求无向图全局最小割
- poj2914(stoer-wagner算法求解全局最小割)
- Stoer-Wagner算法(O(n^3))求全局最小割 hdu3691 2010福州站B题
- POJ_P2914 Minimum Cut(Stoer-Wagner算法 全局最小割)
- poj 2914&&hdu 3002 全局最小割Stoer-Wagner算法模板
- 图的全局最小割的Stoer-Wagner算法及例题
- POJ2914 Minimum Cut 【全局最小割】(Stoer_Wagner)
- poj 2914 Minimum Cut 【无向图全局最小割 Stoer-wagner算法】
- POJ2914 Minimum Cut 【全局最小割Stoer-Wagner模板题】
- 全局最小割Stoer-Wagner算法 时间复杂度(o^3)
- hdu6081 度度熊的王国战略(无向图全局最小割 stoer-wagner)
- POJ 2914 Minimun Cut (Stoer-Wagner, 无向图最小割)
- Stoer-Wagner算法求全局最小割
- Stoer-Wagner无向图全局最小割(hduoj 3691 Nubulsa Expo)
- 【BZOJ3345】Minimum Cut 全局最小割 【Stoer_Wagner算法】
- POJ 2914 Minimum Cut Stoer-Wagner(全局最小割)
- POJ 2914 Minimum Cut【无向图最小割边集stoer-Wagner】
- poj 2914(stoer_wanger算法求全局最小割)
- POJ2914 Minimum Cut【全局最小割】【Stoer-Wangner】
- poj2914——Minimum Cut//最小割Stoer_Wagner