POJ2914 Minimum Cut【全局最小割】【Stoer-Wangner】

题目链接:

http://poj.org/problem?id=2914

题目大意:

提一个无向有重边的图,有重边的边权累加起来,求全局最小割。

思路:

一个无向连通图,去掉一个边集可以使其变成两个连通分量则这个边集就是割集。最小割

集当然就是权和最小的割集。

这是一个最简单的全局最小割模板题。直接套上模板就可以了。来说说Stoer-Wangner算

法吧。

Stoer-Wangner算法:

对于图中的任意两个顶点u和v,若u,v属于最小割的同一个集合中,那么僵顶点u和顶点

v合并后并不影响图的最小割。那么,如果能求出图中某两个顶点之间的最小割,更新答案

后合并这两个顶点继续求最小割,到最后就得到答案了。问题就转变成了求某两点之间的

最小割。

具体步骤:参考ACM-ICPC程序设计系列——图论 P142-146

AC代码:

<span style="font-family:Microsoft YaHei;font-size:18px;">#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 550;
const int MAXM = MAXN*MAXN>>1;
int N,M;

int Map[MAXN][MAXN],Dist[MAXN],Node[MAXN],vis[MAXN];

int Stowag(int N)
{
    int Maxj,pre,m,ans;
    memset(Dist,0,sizeof(Dist));
    memset(vis,0,sizeof(vis));
    for(int i = 0; i < N; ++i)
        Node[i] = i;
    while(N > 1)
    {
        m = -1;
        Maxj = 1;
        for(int i = 1; i < N; ++i)
        {
            Dist[Node[i]] = Map[Node[0]][Node[i]];
            vis[Node[i]] = 0;
            if(Dist[Node[i]] > m)
            {
                m = Dist[Node[i]];
                Maxj = i;
            }
        }
        pre = 0;
        vis[Node[0]] = 1;
        for(int j = 1; j < N; ++j)
        {
            vis[Node[Maxj]] = 1;
            if(j == N-1)
            {
                ans = min(ans,m);
                for(int i = 0; i < N; ++i)
                {
                    Map[Node[pre]][Node[i]] += Map[Node[Maxj]][Node[i]];
                    Map[Node[i]][Node[pre]] += Map[Node[Maxj]][Node[i]];
                }
                Node[Maxj] = Node[--N];
            }
            else
            {
                pre = Maxj;
                m = -1;
                for(int i = 1; i < N; ++i)
                {
                    if(!vis[Node[i]])
                    {
                        Dist[Node[i]] += Map[Node[pre]][Node[i]];
                        if(Dist[Node[i]] > m)
                        {
                            m = Dist[Node[i]];
                            Maxj = i;
                        }
                    }
                }
            }
        }
    }
    return ans;
}

int main()
{
    int u,v,w;
    while(~scanf("%d%d",&N,&M))
    {
        memset(Map,0,sizeof(Map));
        for(int i = 0; i < M; ++i)
        {
            scanf("%d%d%d",&u,&v,&w);
            Map[u][v] += w;
            Map[v][u] += w;
        }
        printf("%d\n",Stowag(N));
    }

    return 0;
}</span>
时间: 2024-10-12 20:26:55

POJ2914 Minimum Cut【全局最小割】【Stoer-Wangner】的相关文章

POJ 2914 - Minimum Cut - 全局最小割,Stoer-Wagner算法

题目大意:给定一个N个点.M条边的无向带权图,边的权值均为正整数.若要使它变成非连通图,需要移除的边总权值最小是多少? N≤500,图中不存在自环,但可能有重边(这里题意没交代清楚). Stoer-Wagner算法裸题.英文维基:https://en.wikipedia.org/wiki/Stoer%E2%80%93Wagner_algorithm 该算法的思想之一是:对于一个无向连通图,选定某两点s,t,以及该图的一个s-t割C,则"C是该图的全局最小割"是"C是s-t的最

POJ 2914 Minimum Cut 全局最小割

裸的全局最小割了吧 有重边,用邻接矩阵的时候要小心 #include<iostream> #include<cstdio> #include<bitset> #include<cstring> #define MOD 1000000007 #define maxn 509 using namespace std; int a[590][590],wage[maxn],in[maxn],vis[maxn]; int n,x,y,v; int find(int&

POJ 2914 Minimum Cut (全局最小割)

[题目链接] http://poj.org/problem?id=2914 [题目大意] 求出一个最小边割集,使得图不连通 [题解] 利用stoerwagner算法直接求出全局最小割,即答案. [代码(递归)] #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int INF=0x3f3f3f3f; const int MAX_N=510; int v

POJ2914 Minimum Cut 最小割集

题目大意是,给定N个顶点,M条边,两个顶点之间可能有多条边,求至少删除多少条边才能将该图分成两个子图. 最小割集,典型的算法Stoer-Wagner,就是那篇论文,这里也就不复制过来了,只是用Prim求最大生成树时,更新的"边"不是普通意义上的边,而是顶点到所有已划分集合中的所有点的边权值和,这里要特别注意~ 直接贴代码~ #include <stdio.h> #include <vector> #include <math.h> #include

图的全局最小割的Stoer-Wagner算法及例题

Stoer-Wagner算法基本思想:如果能求出图中某两个顶点之间的最小割,更新答案后合并这两个顶点继续求最小割,到最后就得到答案. 算法步骤: ------------------------------------------------------------------------------------------------------------------------- (1)首先初始化,设最小割ans = INF                                

全局最小割 学习总结

全局最小割的意思是在一个无向图中任取S和T,求最小割的最小值 还有一种描述是删掉无向图中的边使得其不连通的最小代价 当然,这种题目可以用分治+最小割来求解 但是时间复杂度大约在O(n^4)左右 有一种更好的求解方法可以在O(n^3)的时间复杂度内求解 做法是这样的: 首先对于图中任意两点S->T 要么S和T不在一个集合里时是答案,答案显然是S和T的最小割 否则S和T在一个集合里,我们可以将S和T缩成一个点,不难证明这样是等效的 我们模拟这个过程,每次任取S和T跑最小割,时间复杂度大概跟分治+最小

UVALive 5099 Nubulsa Expo 全局最小割 非网络流 n^3

题目链接:点击打开链接 题意: 给定n个点m条无向边 源点S 下面m行给出无向边以及边的容量. 问: 找一个汇点,使得图的最大流最小. 输出最小的流量. 思路: 最大流=最小割. 所以题意就是找全局最小割. 和源点无关,因为不关心源点在哪个点集里. 模版题: O(n^3) #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std

POJ2914 Minimum Cut 【全局最小割】(Stoer_Wagner)

Minimum Cut Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 7610   Accepted: 3203 Case Time Limit: 5000MS Description Given an undirected graph, in which two vertices can be connected by multiple edges, what is the size of the minimum c

poj 2914 Minimum Cut 无向图最小边割

题意: 求无向图的全局最小边割. 分析: stoer-wagner模板. 代码: //poj 2914 //sep9 #include <iostream> using namespace std; const int maxN=512; int g[maxN][maxN]; int b[maxN],dist[maxN]; int n,m; int Min_Cut_Phase(int ph,int &x,int &y) { int i,j,t; t=1; b[1]=ph; fo