zoukankan      html  css  js  c++  java
  • hdu-2255(带权二分图)

    题解:板子题。。。。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    #include<algorithm>
    #define maxn 1005
    #define inf 0x3f3f3f3f
    using namespace std;
    int ex_l[maxn];
    int ex_r[maxn];
    bool visit_l[maxn];
    bool visit_r[maxn];
    int match[maxn];
    int e[maxn][maxn];
    int slack[maxn];
    int n,m;
    int x,y,w;
    bool dfs(int l)
    {
        visit_l[l]=true;
        for(int r=n+1;r<=2*n;r++)
        {
            if(visit_r[r]==true)
                continue;
            int v=ex_l[l]+ex_r[r]-e[l][r];
            if(v==0)
            {
                visit_r[r]=true;
                if(match[r]==-1||dfs(match[r]))
                {
                    match[r]=l;
                    return true;
                }
            }
            else
                slack[r]=min(slack[r],v);
        }
        return false;
    }
    int km()
    {
        memset(match,-1,sizeof(match));
        memset(ex_r,0,sizeof(ex_r));
        for(int l=1;l<=n;l++)
        {
            ex_l[l]=0;
            for(int r=n+1;r<=2*n;r++)
            {
                ex_l[l]=max(ex_l[l],e[l][r]);
            }
        }
        for(int l=1;l<=n;l++)
        {
            memset(slack,inf,sizeof(slack));
            while(1)
            {
                memset(visit_l,0,sizeof(visit_l));
                memset(visit_r,0,sizeof(visit_r));
                if(dfs(l))
                    break;
                int d=inf;
                for(int r=n+1;r<=2*n;r++)
                {
                    if(!visit_r[r])
                        d=min(d,slack[r]);
                }
                for(int k=1;k<=n;k++)
                {
                    if(visit_l[k])
                        ex_l[k]-=d;
                    if(visit_r[k+n])
                        ex_r[k+n]+=d;
                    else
                        slack[k+n]-=d;
                }
            }
        }
        int ans=0;
        for(int i=n+1;i<=2*n;i++)
        {
            ans+=e[match[i]][i];
        }
        return ans;
    }
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            memset(e,0,sizeof(e));
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    scanf("%d",&x);
                    e[i][j+n]=x;
                }
            }
            printf("%d
    ",km());
        }
        return 0;
    }
    

      

  • 相关阅读:
    【转】 cin、cin.get()、cin.getline()、getline()、gets()等函数的用法
    HDU How many prime numbers
    《大学ACM的总结 》(转载)
    POJ 最小公倍数
    HDU 开门人和关门人
    HDU shǎ崽 OrOrOrOrz
    HDU Saving HDU 2111
    HDU 1106 排序
    strtok函数()
    HDU 2187汶川地震
  • 原文地址:https://www.cnblogs.com/huangdao/p/8985951.html
Copyright © 2011-2022 走看看