【Codeforces1061E】雅礼集训2019Day4T1—Politics(费用流)
想来当初自己还是太了
随便模拟一下建边跑个最大费用流就完了
注意
#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';
}