zoukankan      html  css  js  c++  java
  • Golden Tiger Claw(二分图)

    Golden Tiger Claw

    题意

    找到和最小的两个序列a,b满足对于任意i,j有a[i]+b[j]>=c[i][j](矩阵c给出)。

    solution

    裸的二分图就水过了……

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define clr(a,m) memset(a,m,sizeof(a))
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    
    const int MAXN=555;
    const int INF =1e9;
    const double eps=1e-10;
    
    int gap[MAXN][MAXN];
    int Lx[MAXN],Ly[MAXN],slack[MAXN];
    int left[MAXN],n;
    bool S[MAXN],T[MAXN];
    
    void read()
    {
        rep(i,1,n)
            rep(j,1,n)
                scanf("%d",&gap[i][j]);
    }
    
    bool match(int u)
    {
        S[u]=true;
        rep(v,1,n)
            if(!T[v]){
                int tmp=Lx[u]+Ly[v]-gap[u][v];
                if(tmp==0){
                    T[v]=true;
                    if(!left[v]||match(left[v])){
                        left[v]=u;
                        return true;
                    }
                }else slack[v]=min(slack[v],tmp);
            }
        return false;
    }
    
    void update()
    {
        int a=INF;
        rep(v,1,n)
            if(!T[v])
                a=min(a,slack[v]);
        rep(i,1,n){
            if(S[i])Lx[i]-=a;
            if(T[i])Ly[i]+=a;
        }
    }
    
    void KM()
    {
        rep(i,1,n){
            left[i]=Ly[i]=0;
            Lx[i]=-INF;
            rep(j,1,n)
                Lx[i]=max(Lx[i],gap[i][j]);
        }
        rep(i,1,n){
            rep(j,1,n)
                slack[j]=INF;
            while(1)
            {
                rep(j,1,n)
                    S[j]=T[j]=0;
                if(match(i))
                    break;
                else
                    update();
            }
        }
    }
    
    void print()
    {
        int ans=0;
        rep(i,1,n){
            ans+=Lx[i];
            if(i!=1)printf(" ");
            printf("%d",Lx[i]);
    
        }
        printf("
    ");
        rep(i,1,n){
            ans+=Ly[i];
            if(i!=1)printf(" ");
            printf("%d",Ly[i]);
        }
        printf("
    ");
        printf("%d
    ",ans);
    }
    
    int main()
    {
        while(~scanf("%d",&n))
        {
            read();
            KM();
            print();
        }
        return 0;
    }
    
  • 相关阅读:
    Spring boot test
    SQL怎么输出前n个记录? n是中间计算得到的,不支持变量传递
    crontab 命令
    Python 素数判断;以及默尼森数
    精通Web Analytics 2.0 (1) 引言
    Python 编程小备忘
    Python 编辑器 tips
    Hadoop 权威指南学习1 (主要框架)
    ml的线性回归应用(python语言)
    python 学习5--matplotlib画图实践
  • 原文地址:https://www.cnblogs.com/rui-4825/p/12870759.html
Copyright © 2011-2022 走看看