zoukankan      html  css  js  c++  java
  • 小M的作物 最大权闭合子图

    题目大意

    bzoj 3438
    两个田(A,B)
    (nle 1000)种作物的种子
    (i)个种子,种(A)价值(a[i]),种(B)价值(b[i])
    再给出(m)个子集
    (i)个子集,如果子集中的点都种(A)增价(c[i]),都种(B)增价(d[i])
    求最大的价值

    分析

    我们看(A)高兴,我们先都种(A),那么我们直接拿到所有(a,c)
    我们对方案进行修正
    把子集看成点,我们把一个子集拆点拆成(S_1,S_2)
    (S_1)表示不要(c),选(S_2)表示要(d)
    如果选一个种子(i),那么把它种到(B),变价(b[i]-a[i]),包含它的子集的(S_1)都要选
    如果要选择(S_2),则该子集中的种子都要选
    有了依赖关系和正权负权
    跑一个最大权闭合子图即可

    solution

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cctype>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    const int M=3007;
    const int N=2100007;
    const int INF=1e9+7;
    
    inline int rd(){
    	int x=0;bool f=1;char c=getchar();
    	for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
    	for(;isdigit(c);c=getchar()) x=x*10+c-48;
    	return f?x:-x;
    }
    
    struct vec{
    	int g[M],te;
    	struct edge{
    		int y,f,nxt;
    		edge(int _y=0,int _f=0,int _n=0){y=_y,f=_f,nxt=_n;}
    	}e[N];
    	vec(){te=1;}
    	inline void push(int x,int y,int f){
    		e[++te]=edge(y,f,g[x]);g[x]=te;
    		e[++te]=edge(x,0,g[y]);g[y]=te;
    	}
    	inline int& operator () (int x){return g[x];}
    	inline edge& operator [] (int x){return e[x];}
    }e;
    
    int n,m,res;
    int S,T;
    int a[M],b[M];
    int c[M],d[M];
    
    inline int id1(int x){return n+x;}
    inline int id2(int x){return n+m+x;}
    
    int lev[M];
    
    bool bfs(){
    	static int q[M];
    	int h=0,t=1,x,p,y;
    	memset(lev,0,sizeof(lev));
    	lev[S]=1; q[1]=S;
    	while(h^t){
    		x=q[++h];
    		for(p=e(x);p;p=e[p].nxt)
    		if(e[p].f&&lev[y=e[p].y]==0){
    			lev[y]=lev[x]+1;
    			if(y==T) return 1;
    			q[++t]=y;
    		}
    	}
    	return 0;
    }
    
    int dfs(int x,int fl){
    	if(x==T) return fl;
    	int p,y,res=0,tp;
    	for(p=e(x);p;p=e[p].nxt)
    	if(e[p].f&&lev[x]+1==lev[y=e[p].y]){
    		tp=dfs(y,min(fl,e[p].f));
    		if(tp){
    			res+=tp;
    			fl-=tp;
    			e[p].f-=tp;
    			e[p^1].f+=tp;
    			if(fl==0) return res;
    		}
    	}
    	if(res==0) lev[x]=0;
    	return res;
    }
    
    int main(){
    
    	int i,j,x,y,z,tp;
    
    	n=rd();
    	for(i=1;i<=n;i++) a[i]=rd();
    	for(i=1;i<=n;i++) b[i]=rd();
    
    	m=rd();
    	for(i=1;i<=m;i++){
    		z=rd(),c[i]=rd(),d[i]=rd();
    		x=id1(i),y=id2(i);
    		for(j=1;j<=z;j++){
    			tp=rd();
    			e.push(tp,x,INF);
    			e.push(y,tp,INF);
    		}
    	}
    
    	S=0; T=id2(m)+1;
    
    	for(i=1;i<=n;i++){
    		res+=a[i];
    		tp=b[i]-a[i];
    		if(tp>0) e.push(S,i,tp),res+=tp;
    		else e.push(i,T,-tp);
    	}
    
    	for(i=1;i<=m;i++){
    		res+=c[i];
    		x=id1(i),y=id2(i);
    		e.push(x,T,c[i]);
    		e.push(S,y,d[i]),res+=d[i];
    	}
    
    	while(bfs()) res-=dfs(S,INF);
    
    	printf("%d
    ",res);
    	
    	return 0;
    }
    
    
  • 相关阅读:
    WebRTC视频采集中的约束有哪些和具体的使用方法
    解决WebRTC中不同的浏览器之间适配的问题
    WebRTC如何获取音频视频设备
    用C#调用外部DLL
    null值与非null只比较大小时,只会返回false
    jsonp实现js跨域请求
    同一域名的ASP.NET网站实现Session共享
    machinekey相关信息
    从bbs.3dmgame.com与qq的登录解析oauth2.0协议
    asp.net使用wsdl文件调用接口,以及调用SSL接口报错“根据验证过程 远程证书无效”的处理
  • 原文地址:https://www.cnblogs.com/acha/p/6708405.html
Copyright © 2011-2022 走看看