【Codeforces1061E】雅礼集训2019Day4T1—Politics(费用流)

传送门

想来当初自己还是太naivenaive

随便模拟一下建边跑个最大费用流就完了
注意b=0b=0的情况

#include<bits/stdc++.h>
using namespace std;
const int RLEN=1<<20|1;
inline char gc(){
	static char ibuf[RLEN],*ib,*ob;
	(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
	return (ib==ob)?EOF:*ib++;
} 
#define gc getchar
inline int read(){
	char ch=gc();
	int res=0,f=1;
	while(!isdigit(ch))f^=ch=='-',ch=gc();
	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
	return f?res:-res;
}
#define pb push_back
#define ll long long
#define int long long
namespace Flow{
	#define N 1010
	#define M 1000005
	int cnt=1,str,des,adj[N],nxt[M],to[M],cap[M],val[M],dis[N],tp[N],vis[N];
	int mxflow,mncost;
	inline void add(int u,int v,int w,int c){
		nxt[++cnt]=adj[u],adj[u]=cnt,to[cnt]=v,cap[cnt]=w,val[cnt]=c;
		nxt[++cnt]=adj[v],adj[v]=cnt,to[cnt]=u,cap[cnt]=0,val[cnt]=-c;
	}
	inline bool spfa(){
		queue<int> q;
		memset(vis,0,sizeof(vis));
		memset(dis,127/3,sizeof(dis));
		dis[str]=0,q.push(str),vis[str]=1;
		while(!q.empty()){
			int u=q.front();q.pop();
			vis[u]=0;
			for(int e=adj[u];e;e=nxt[e]){
				int v=to[e];
				if(cap[e]>0&&dis[v]>dis[u]+val[e]){
					dis[v]=dis[u]+val[e];
					if(!vis[v])q.push(v),vis[v]=1;
				}
			}
		}
		return dis[des]<dis[0];
	}
	int dfs(int u,int flow){
		vis[u]=1;if(u==des)return flow;
		int res=0;
		for(int &e=tp[u];e;e=nxt[e]){
			int v=to[e];
			if((!vis[v]||v==des)&&cap[e]>0&&dis[v]==dis[u]+val[e]){
				int now=dfs(v,min(cap[e],flow-res));
				res+=now,cap[e]-=now,cap[e^1]+=now,mncost+=val[e]*now;
				if(res==flow)break;
			}
		}
		return res;
	}
	inline void mcmf(){
		while(spfa()){
			memcpy(tp,adj,sizeof(adj));
			mxflow+=dfs(str,1e9);
		}
	}
	#undef N
	#undef M
}
const int N=505;
int in,out;
int n,rt1,rt2,a[N];
struct tree{
	vector<int> e[N],son[N];
	int bel[N],b[N];
	inline void init(){
		memset(b,-1,sizeof(b));
	}
	inline void add(int u,int v){
		e[u].pb(v),e[v].pb(u);
	}
	int dfs(int u,int fa,int f){
		int res=0;son[u].pb(u);
		for(int &v:e[u]){
			if(v==fa)continue;
			res+=dfs(v,u,f);
			for(int &p:son[v])son[u].pb(p);
		}
		if(b[u]!=-1){
			if(b[u]<res){puts("-1"),exit(0);}
			if(!f) Flow::add(Flow::str,u,b[u]-res,0),in+=b[u]-res;
			else Flow::add(u+n,Flow::des,b[u]-res,0),out+=b[u]-res;
			for(int &p:son[u])bel[p]=u;
			son[u].clear();return b[u];
		}
		return res;
	}
}t[2];
signed main(){
	#ifdef Stargazer
	freopen("lx.cpp","r",stdin);
	#endif
	n=read(),rt1=read(),rt2=read();
	Flow::str=2*n+1,Flow::des=Flow::str+1;
	t[0].init(),t[1].init();
	for(int i=1;i<=n;i++)a[i]=read();
	for(int i=1;i<n;i++){
		int u=read(),v=read();
		t[0].add(u,v);
	}
	for(int i=1;i<n;i++){
		int u=read(),v=read();
		t[1].add(u,v);
	}
	for(int i=1,q=read();i<=q;i++){
		int u=read();t[0].b[u]=read();
	}
	for(int i=1,q=read();i<=q;i++){
		int u=read();t[1].b[u]=read();
	}
	t[0].dfs(rt1,0,0),t[1].dfs(rt2,0,1);
	for(int i=1;i<=n;i++)Flow::add(t[0].bel[i],t[1].bel[i]+n,1,-a[i]);
	if(in!=out){puts("-1"),exit(0);}
	Flow::mcmf();
	if(Flow::mxflow!=in){puts("-1"),exit(0);}
	cout<<-Flow::mncost<<'\n';
}
posted @ 2019-07-24 21:04  Stargazer_cykoi  阅读(100)  评论(0编辑  收藏  举报