• BZOJ2039_employ人员雇佣_KEY


    题目传送门

    网络流,求最小割。

    设tot为所有盈利的和,即所有人(不花钱)雇佣。

    对于S->i建一条容量为c[i]的边,i->j建一条S[i][j]*2的边,之所以这样建是因为如果不选这个人还会亏S[i][j]。

    对于i->T建一条容量为∑S[i][j]的边。

    最小割=最大流,跑Dinic

    code:

    /**************************************************************
        Problem: 2039
        User: yekehe
        Language: C++
        Result: Accepted
        Time:4428 ms
        Memory:52316 kb
    ****************************************************************/
     
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
     
    int read()
    {
        char c;while(c=getchar(),c<'0'||c>'9');
        int x=c-'0';while(c=getchar(),c>='0'&&c<='9')x=x*10+c-'0';
        return x;
    }
     
    int N,a[1005],MP[1005][1005];
    int head[1005],nxt[10040005],To[1004005],W[1004005],cnt;
     
    void add(int x,int y,int c)
    {
        To[cnt]=y,W[cnt]=c;
        nxt[cnt]=head[x];
        head[x]=cnt;
        cnt++;
    }
     
    int dist[1005],l[1005],h,t;
    int BFS()
    {
        h=t=0;
        memset(dist,0xfff,sizeof dist);
        l[++t]=0,dist[0]=1;
            while(h<t){
                int front=l[++h];
                    for(int i=head[front];i!=-1;i=nxt[i]){
                        if(dist[To[i]]==-1 && W[i]){
                            dist[To[i]]=dist[front]+1;
                            l[++t]=To[i];
                        }
                    }
            }
        return dist[N+1]!=-1;
    }
     
    int DFS(int x,int w)
    {
        if(x==N+1 || !w)return w;
        int res=0;
            for(int i=head[x];i!=-1&&w;i=nxt[i]){
                if(dist[x]+1==dist[To[i]] && W[i]){
                    int DK=DFS(To[i],min(w,W[i]));
                    res+=DK;w-=DK;
                    W[i]-=DK,W[i^1]+=DK;
                }
            }
        if(!res)dist[x]=-1;
        return res;
    }
     
    int tot=0;
    void Dinic()
    {
        int ans=0;
            while(BFS())
                ans+=DFS(0,2e9);
        printf("%d",tot-ans);
        return ;
    }
     
    int main()
    {
        memset(head,-1,sizeof head);
        memset(nxt,-1,sizeof nxt);
        N=read();
        register int i,j;
            for(i=1;i<=N;i++)
                a[i]=read(),add(0,i,a[i]),add(i,0,0);
            for(i=1;i<=N;i++)
                for(j=1;j<=N;j++)
                    MP[i][j]=read(),tot+=MP[i][j];
            for(i=1;i<=N;i++)
                for(j=i+1;j<=N;j++)
                    add(i,j,MP[i][j]<<1),add(j,i,MP[i][j]<<1);
            for(i=1;i<=N;i++){
                int res=0;for(j=1;j<=N;j++)res+=MP[i][j];
                add(i,N+1,res),add(N+1,i,0);
            }
        Dinic();
        return 0;
    }
  • 相关阅读:
    sql 存储过程 in 的两种写法
    C# 开发Chrome内核浏览器(WebKit.net)
    IE6、IE7、IE8、Firefox兼容性
    360浏览器兼容模式 不能$.post (不是a 连接 onclick的问题!!)
    jquery树形表格实现方法
    C#递归累计到父行
    树形结构 DropDownList
    ASP.NET 防止重复提交提示层
    JavaScriptSerializer 时间格式化
    去标签获取网页内容
  • 原文地址:https://www.cnblogs.com/Cptraser/p/8581706.html
Copyright © 2020-2023  润新知