• 【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<<'
    ';
    }
    
  • 相关阅读:
    MVC的布局页,视图布局页和分布页的使用
    C#程序的编译过程
    页面跳转到Area区域连接
    c#静态变量和非静态变量的区别
    C#设计模式:适配器模式(Adapter Pattern)
    依赖注入
    打印随机数到字符串中
    printf/scanf格式
    用fread和fwrite实现文件复制操作
    用fseek和ftell获取文件的大小
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328763.html
Copyright © 2020-2023  润新知