zoukankan      html  css  js  c++  java
  • P1791-[国家集训队]人员雇佣【最大权闭合图】

    正题

    题目链接:https://www.luogu.com.cn/problem/P1791


    题目大意

    (n)个人,雇佣第(i)个需要(A_i)的费用,对于(E_{i,j})表示如果(i)选了的话,选择(j)会获得(E_{i,j})的费用,不选(j)会花费(E_{i,j})的费用。

    (1leq nleq 1000)


    解题思路

    考虑网最大权值闭合图,先加上所有可以获得的权值,然后考虑需要失去的最小权值。

    因为每个人可以选或者不选,那么就可以让(s)连接(i)(i)连接(t)这样两边必须割掉一条表示选择或者不选择。

    考虑让(s->i)表示选择,那么(s->i)权值为(A_i)

    (i->t)表示不选择那么所有由(i)产生的费用都不能获得,权值为(sum_{j=1}^mE_{i,j})

    然后对于一个(E_{i,j})如果(i)选择了且(j)没有选择那么就会失去(2 imes E_{i,j})的流量,在(i)(j)之间连一条(2 imes E_{i,j})的就好了。


    code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #define ll long long
    using namespace std;
    const ll N=2e4+10,inf=2147483647;
    struct node{
    	ll to,next,w;
    }a[N*4];
    ll n,s,t,tot,cnt,A[N],ls[N],dep[N],ans;
    queue<int> q;
    void addl(ll x,ll y,ll w){
    	a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;a[tot].w=w;
    	a[++tot].to=x;a[tot].next=ls[y];ls[y]=tot;a[tot].w=0;
    	return;
    }
    bool bfs(){
    	memset(dep,0,sizeof(dep));dep[s]=1;
    	while(!q.empty())q.pop();q.push(s);
    	while(!q.empty()){
    		ll x=q.front();q.pop();
    		for(ll i=ls[x];i;i=a[i].next){
    			ll y=a[i].to;
    			if(dep[y]||!a[i].w)continue;
    			dep[y]=dep[x]+1;
    			if(y==t)return 1;
    			q.push(y);
    		}
    	}
    	return 0;
    }
    ll dinic(ll x,ll flow){
    	if(x==t)return flow;
    	ll rest=0,k;
    	for(ll i=ls[x];i;i=a[i].next){
    		ll y=a[i].to;
    		if(dep[y]!=dep[x]+1||!a[i].w)continue;
    		rest+=(k=dinic(y,min(a[i].w,flow-rest)));
    		a[i].w-=k;a[i^1].w+=k;
    		if(rest==flow)return flow;
    	}
    	if(!rest)dep[x]=0;
    	return rest;
    }
    signed main()
    {
    	scanf("%lld",&n);
    	s=n+1;t=s+1;tot=1;
    	for(ll i=1;i<=n;i++){
    		ll x;
    		scanf("%lld",&x);
    		addl(s,i,x);
    	}
    	for(ll i=1;i<=n;i++){
    		ll S=0;
    		for(ll j=1;j<=n;j++){
    			ll x;scanf("%lld",&x);
    			if(!x)continue;
    			S+=x;addl(i,j,2*x);
    		}
    		addl(i,t,S);ans+=S;
    	}
    	while(bfs())
    		ans-=dinic(s,inf);
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    mybatis 绑定 statement 失败
    JDBC链接Mysql失败
    Mysql 链接数据库时区错误
    mybatis 延迟加载
    C++ 虚函数表解析
    运行错误:error while loading shared libraries: xxx.so.0:cannot open shared object file: No such file or
    QComboBox的activated与currentIndexChanged的区别
    QT 文件对话框(QFileDialog)
    VS2010 ERROR:c1xx fatal error c1083
    django 在字符串[str(list)]中精确查找
  • 原文地址:https://www.cnblogs.com/QuantAsk/p/15015750.html
Copyright © 2011-2022 走看看