hdu 3691 Nubulsa Expo

 

http://acm.hdu.edu.cn/showproblem.php?pid=3691

Stoer-Wagner算法 不理解不理解呀

大体步骤是这样子的

1,用类似Prim 的过程求得最后更新点 和倒数第二更新点

2,求最后更新点和其它点的割集

3,将最后一个点合并到倒数第二个更新点上

代码:

#include<iostream>

#include<cstdio>

#include<cstring>



using namespace std;



const int INF=0x7fffffff;

const int N=305;

int a[N][N];

int dist[N];

bool visited[N],dele[N];

int n,m,st;

int nd1,nd2;

void Prim()

{

    memset(dist,0,sizeof(dist));

    for(int i=1;i<=n;++i)

    {

        if(!dele[i])

        {

            dist[i]=a[st][i];

        }

    }

    nd1=nd2=st;

    memset(visited,false,sizeof(visited));

    visited[st]=true;

    for(int w=1;w<n;++w)

    {

        int M=0,k=0;

        for(int i=1;i<=n;++i)

        {

            if(!dele[i]&&!visited[i]&&dist[i]>M)

            {

                M=dist[i];k=i;

            }

        }

        if(k==0)

        break;

        visited[k]=true;

        for(int i=1;i<=n;++i)

        {

            if(!dele[i]&&!visited[i])

            {

                dist[i]+=a[k][i];//这里好奇怪

            }

        }

        nd2=nd1;//最后更新点 和倒数第二更新点

        nd1=k;

    }

    return;

}

int Findmin()

{

    int sum=0;

    for(int i=1;i<=n;++i)

    {

        if(!dele[i])

        {

            sum+=a[nd1][i];//最后更新点的割集

        }

    }

    return sum;

}

void Removepoint()

{

    dele[nd1]=true;

    for(int i=1;i<=n;++i)

    {

        if(!dele[i]&&i!=nd2)

        {

            a[i][nd2]+=a[i][nd1];//合并最后更新点

            a[nd2][i]+=a[nd1][i];

        }

    }

}

int main()

{

    while(scanf("%d %d %d",&n,&m,&st)!=EOF)

    {

        if(!n&&!m&&!st)

        break;

        memset(a,0,sizeof(a));

        while(m--)

        {

            int i,j,k;

            scanf("%d %d %d",&i,&j,&k);

            a[i][j]+=k;//重边

            a[j][i]+=k;

        }

        int ans=INF;

        memset(dele,false,sizeof(dele));//此点是否删除

        for(int w=1;w<n;++w)

        {

            Prim();

            ans=min(ans,Findmin());

            Removepoint();

        }

        printf("%d\n",ans);

    }

    return 0;

}

 

 

 

你可能感兴趣的:(exp)