码农场 » POJ 2914 Minimum Cut 题解 《挑战程序设计竞赛》

来源:互联网 发布:云计算相关论文 编辑:程序博客网 时间:2024/05/29 13:19
#include <iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;const int INF = 1000000000;int n,m,g[505][505],v[505],w[505];bool visited[505];int mincut(){    int ans=INF;    for(int i=0;i<n;i++)        v[i]=i;    while(n>1)    {        int pre=0;        memset(visited,0,sizeof(visited));        memset(w,0,sizeof(w));        for(int i=1;i<n;i++)        {            int k=-1;            for(int j=1;j<n;j++)            {                if(!visited[v[j]])                {                    w[v[j]]+=g[v[pre]][v[j]];                    if(k==-1||w[v[j]]>w[v[k]])                        k=j;                }            }            visited[v[k]]=true;            if(i==n-1)//合并两点            {                int &s=v[pre],&t=v[k];                ans=min(ans,w[t]);                for(int j=0;j<n;j++)                {                  g[s][v[j]]+=g[t][v[j]];                  g[v[j]][s]+=g[t][v[j]];                }                v[k]=v[--n];            }            pre=k;        }    }    return ans;}int main(){    while(cin>>n>>m)    {        int s,t,cost;        memset(g,0,sizeof(g));        for(int i=0;i<m;i++)        {            scanf("%d%d%d",&s,&t,&cost);            g[s][t]+=cost;            g[t][s]+=cost;        }        printf("%d\n",mincut());    }    return 0;}

本题是求最小割的问题,使用了stoer_wagner最小割算法

有点类似prim

①:如果s∈M,t∈N则Min-C(s,t)= Cut(这就是最终的最小割了)

②:如果s,t∈M(或者s,t∈N)则Min-C(s,t)<= Cut(那么合并s和t后并不影响最小割,所以就把st合并了得到中间结果图G',继续在图G'上求最小割直到命中条件①

本题的关键在于合并思想
0 0
原创粉丝点击