zoukankan      html  css  js  c++  java
  • bzoj 2039: [2009国家集训队]employ人员雇佣【最小割】

    一开始在https://www.cnblogs.com/lokiii/p/10770919.html基础上连(i,j,b[i][j])建了个极丑的图T掉了……把dinic换成isap勉强能卡过
    首先因为有正负收益所以考虑最小割,先ans=Σb,然后考虑负收益
    把割完后和s相邻的视为不选,反之视为选,选的话要付出代价a,所以连(s,i,a[i]);然后考虑如果ij一个选一个不选(这里是单向的),需要Eij的代价,所以连(i,j,E[i][j]);然后是如果一个点不选的话那么所有Eij都不会被加,所以连边(i,t,ΣE[i][j])
    跑最小割即可

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    using namespace std;
    const int N=1005;
    int n,s,t,h[N],cnt=1,le[N];
    long long b[N][N],ans;
    struct qwe
    {
        int ne,to;
        long long va;
    }e[N*N*4];
    int read()
    {
        int r=0,f=1;
        char p=getchar();
        while(p>'9'||p<'0')
        {
            if(p=='-')
                f=-1;
            p=getchar();
        }
        while(p>='0'&&p<='9')
        {
            r=r*10+p-48;
            p=getchar();
        }
        return r*f;
    }
    void add(int u,int v,long long w)
    {
        cnt++;
        e[cnt].ne=h[u];
        e[cnt].to=v;
        e[cnt].va=w;
        h[u]=cnt;
    }
    void ins(int u,int v,long long w)
    {
        add(u,v,w);
        add(v,u,0);
    }
    bool bfs()
    {
        memset(le,0,sizeof(le));
        queue<int>q;
        le[s]=1;
        q.push(s);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            for(int i=h[u];i;i=e[i].ne)
                if(e[i].va>0&&!le[e[i].to])
                {
                    le[e[i].to]=le[u]+1;
                    q.push(e[i].to);
                }
        }
        return le[t];
    }
    long long dfs(int u,long long f)
    {
        if(u==t||!f)
            return f;
        long long us=0;
        for(int i=h[u];i&&us<f;i=e[i].ne)
            if(e[i].va>0&&le[e[i].to]==le[u]+1)
            {
                long long t=dfs(e[i].to,min(e[i].va,f-us));
                e[i].va-=t;
                e[i^1].va+=t;
                us+=t;
            }
        if(!us)
            le[u]=0;
        return us;
    }
    long long dinic()
    {
        long long r=0;
        while(bfs())
            r+=dfs(s,1e11);
        return r;
    }
    int main()
    {
        n=read();
        s=0,t=n+1;
        for(int i=1;i<=n;i++)
            ins(s,i,read());
        for(int i=1;i<=n;i++)
    	{
    		long long sm=0;
            for(int j=1;j<=n;j++)
            {
                b[i][j]=read();
    			if(b[i][j])
    				sm+=b[i][j],ans+=b[i][j],ins(i,j,b[i][j]<<1);
            }
    		ins(i,t,sm);
    	}
        printf("%lld
    ",ans-dinic());
        return 0;
    }
    
  • 相关阅读:
    hdu 4710 Balls Rearrangement()
    hdu 4707 Pet(DFS水过)
    hdu 4706 Children's Day(模拟)
    hdu 4712 Hamming Distance(随机函数暴力)
    csu 1305 Substring (后缀数组)
    csu 1306 Manor(优先队列)
    csu 1312 榜单(模拟题)
    csu 1303 Decimal (数论题)
    网络爬虫
    Python处理微信利器——itchat
  • 原文地址:https://www.cnblogs.com/lokiii/p/10772840.html
Copyright © 2011-2022 走看看