luogu P1361 小M的做物 |網絡流

題目描述

小M在MC裏開闢了兩塊巨大的耕地A和B(你能夠認爲容量是無窮),如今,小P有n中做物的種子,每種做物的種子有1個(就是能夠種一棵做物)(用1...n編號)。ios

如今,第i種做物種植在A中種植能夠得到ai的收益,在B中種植能夠得到bi的收益,並且,如今還有這麼一種神奇的現象,就是某些做物共同種在一塊耕地中能夠得到額外的收益,小M找到了規則中共有m種做物組合,第i個組合中的做物共同種在A中能夠得到c1i的額外收益,共同總在B中能夠得到c2i的額外收益。spa

小M很快的算出了種植的最大收益,可是他想要考考你,你能回答他這個問題麼?rest

輸入格式

第一行包括一個整數ncode

第二行包括n個整數,表示ai第三行包括n個整數,表示bi第四行包括一個整數m接下來m行,get

對於接下來的第i行:第一個整數ki,表示第i個做物組合中共有ki種做物,string

接下來兩個整數c1i,c2i,接下來ki個整數,表示該組合中的做物編號。io

輸出格式

只有一行,包括一個整數,表示最大收益class


#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
inline int read(){
    int s = 0, w = 1; char ch = getchar();
    while(ch < '0' || ch > '9'){ if(ch == '-') w = -1; ch = getchar();}
    while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
    return s * w;
}
const int N=500005,M=10*N,inf=1<<30;
int nxt[M],head[N],go[M],edge[M],tot=1;
inline void add(int u,int v,int w){
	nxt[++tot]=head[u],head[u]=tot,go[tot]=v,edge[tot]=w;
	nxt[++tot]=head[v],head[v]=tot,go[tot]=u,edge[tot]=0;
}
int n,m,s,t,maxflow=0;
int d[N];
inline bool bfs(){
	memset(d,0,sizeof(d));
	queue<int>q; 
	q.push(s); d[s]=1;
	while(q.size()){
		int u=q.front(); q.pop();
		for(int i=head[u];i;i=nxt[i]){
			int v=go[i];
			if(edge[i]&&!d[v]){
				d[v]=d[u]+1;
				q.push(v);
				if(v==t)return 1;	
			}
		}
	}
	return 0;
}

int dinic(int u,int flow){
	if(u==t)return flow;
	int rest=flow;
	for(int i=head[u];i&&rest;i=nxt[i]){
		int v=go[i];
		if(edge[i]&&d[v]==d[u]+1){
			int k=dinic(v,min(rest,edge[i]));
			if(!k)d[v]=-1;
			edge[i]-=k;
			edge[i^1]+=k;
			rest-=k;
		}
	}
	return flow-rest;
}

signed main(){
	int ans=0;
	n=read();
	s=0,t=5*n+1;
	for(int i=1,x;i<=n;i++){
		x=read();
		ans+=x;
		add(s,i,x);
	}
	for(int i=1,x;i<=n;i++){
		x=read();
		ans+=x;
		add(i,t,x);
	}
	m=read();
	for(int i=1,x,y,c1,c2;i<=m;i++){
		x=read(),c1=read(),c2=read();
		ans+=c1+c2;
		add(s,n+i,c1);
		add(m+n+i,t,c2);
		while(x--){
			y=read();
			add(n+i,y,inf);
			add(y,n+m+i,inf);
		}
	}
	
	int flow=0;
	while(bfs())
	while(flow=dinic(s,inf))maxflow+=flow;
	cout<<ans-maxflow<<endl;
}
相關文章
相關標籤/搜索