zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    When You Get Troubles
    CentOS 6.8升级到7+
    Tomcat服务器搭建
    Percona Server 安装
    VirtualBox中如何使虚拟机能够上网?
    CentOS
    xen安装
    SSH免密码设置
    打造绿色版的RobotFramework
    零散知识记录-Jira的安装
  • 原文地址:https://www.cnblogs.com/liulangye/p/2541386.html
Copyright © 2011-2022 走看看