• UVA-11383 Golden Tiger Claw (KM算法)


    题目大意:一张可行二分图的权值以邻接矩阵的形式给了出来,现在要找每一个节点的可行顶标,使顶标和最小。

    题目分析:直接用KM算法,结束后顶标之和最小。。。模板题。

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<queue>
    # include<cmath>
    # include<vector>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    # define LL long long
    # define REP(i,s,n) for(int i=s;i<n;++i)
    # define CL(a,b) memset(a,b,sizeof(a))
    # define CLL(a,b,n) fill(a,a+n,b)
    
    const int N=505;
    const int INF=1<<30;
    int w[N][N],lx[N],ly[N],n;
    int link[N],visx[N],visy[N],slack[N];
    
    bool match(int x)
    {
        visx[x]=1;
        REP(y,1,n+1){
            if(visy[y]) continue;
            int t=lx[x]+ly[y]-w[x][y];
            if(t==0){
                visy[y]=1;
                if(link[y]==-1||match(link[y])){
                    link[y]=x;
                    return true;
                }
            }else if(slack[y]>t)
                slack[y]=t;
        }
        return false;
    }
    
    void update()
    {
        int d=INF;
        REP(i,1,n+1) if(!visy[i])
            d=min(d,slack[i]);
        REP(i,1,n+1) if(visx[i]) lx[i]-=d;
        REP(i,1,n+1){
            if(visy[i]) ly[i]+=d;
            else slack[i]-=d;
        }
    }
    
    void KM()
    {
        CL(link,-1);
        CL(ly,0);
        REP(i,1,n+1){
            lx[i]=-1;
            REP(j,1,n+1)
                lx[i]=max(lx[i],w[i][j]);
        }
        REP(x,1,n+1){
            CLL(slack,INF,n+1);
            while(1){
                CL(visx,0);
                CL(visy,0);
                if(match(x)) break;
                update();
            }
        }
    }
    
    int main()
    {
        int T=15;
        while(T--)
        {
            scanf("%d",&n);
            REP(i,1,n+1) REP(j,1,n+1) scanf("%d",&w[i][j]);
            KM();
            REP(i,1,n+1) printf("%d%c",lx[i],(i==n)?'
    ':' ');
            REP(i,1,n+1) printf("%d%c",ly[i],(i==n)?'
    ':' ');
            int sum=0;
            REP(i,1,n+1) sum+=lx[i]+ly[i];
            printf("%d
    ",sum);
        }
        return 0;
    }
    

      

  • 相关阅读:
    oracle 10g 免安装客户端在windows下配置
    sql2005 sa密码
    使用windows live writer 有感
    windows xp SNMP安装包提取
    汉化groove2007
    迁移SQL server 2005 Reporting Services到SQL server 2008 Reporting Services全程截图操作指南
    foxmail 6在使用中的问题
    AGPM客户端连接不上服务器解决一例
    SpringSource Tool Suite add CloudFoundry service
    Java 之 SWing
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/4936182.html
Copyright © 2020-2023  润新知