码迷,mamicode.com
首页 > 其他好文 > 详细

cf1061E Politics (费用流)

时间:2018-12-01 21:49:30      阅读:215      评论:0      收藏:0      [点我收藏+]

标签:return   ons   spfa   empty   std   lin   完全   i++   name   

看到数据范围,考虑网络流..但考的时候完全不知道怎么建图

考虑流量表示选的点个数,费用表示选点的收益,跑最大费用最大流

那么我用一个点x表示某树中的询问点x,刨去它子孙询问点的子树后的子树

对于树1,连边S->x,流量为x的限定数-孩子询问的限定数,费用为0

对于树2,连边x->T,流量为x的限定数-孩子询问的限定数,费用为0

以限制数量

之后对于每个点,给它在树1中最近的询问祖先到树2中最近的询问祖先 连边,流量为1,费用为点权

表示选这个点

如果S的出流量和不等于T的入流量和,或者最后没跑满,则说明无解

  1 #include<bits/stdc++.h>
  2 #define CLR(a,x) memset(a,x,sizeof(a))
  3 #define MP make_pair
  4 using namespace std;
  5 typedef long long ll;
  6 typedef unsigned long long ull;
  7 typedef pair<int,int> pa;
  8 const int maxn=505;
  9 
 10 inline ll rd(){
 11     ll x=0;char c=getchar();int neg=1;
 12     while(c<0||c>9){if(c==-) neg=-1;c=getchar();}
 13     while(c>=0&&c<=9) x=x*10+c-0,c=getchar();
 14     return x*neg;
 15 }
 16 
 17 int teg[2][maxn*2][2],tegh[2][maxn],tect[2];
 18 int dem[2][maxn],cfa[2][maxn],rt[2];
 19 inline void adteg(int o,int a,int b){
 20     teg[o][++tect[o]][0]=b,teg[o][tect[o]][1]=tegh[o][a],tegh[o][a]=tect[o];
 21     teg[o][++tect[o]][0]=a,teg[o][tect[o]][1]=tegh[o][b],tegh[o][b]=tect[o];
 22 }
 23 struct Edge{
 24     int b,l,c,ne;
 25 }eg[maxn*6];
 26 int N,egh[maxn*2],ect=1,S=1004,T=1005;
 27 int val[maxn],inl,outl;
 28 
 29 inline void ext(){
 30     printf("-1\n");
 31     exit(0);
 32 }
 33 
 34 inline void adeg(int a,int b,int l,int c){
 35     if(a==S) inl+=l;
 36     if(b==T) outl+=l;
 37     eg[++ect]=(Edge){b,l,c,egh[a]},egh[a]=ect;
 38     eg[++ect]=(Edge){a,0,-c,egh[b]},egh[b]=ect;
 39 }
 40 inline int dfs(int o,int x,int f,int cl){
 41     if(dem[o][x]) cl=x;
 42     cfa[o][x]=cl;
 43     int n=0;
 44     for(int i=tegh[o][x];i;i=teg[o][i][1]){
 45         int b=teg[o][i][0];if(b==f) continue;
 46         n+=dfs(o,b,x,cl);
 47     }
 48     if(dem[o][x]){
 49         if(dem[o][x]<n) ext();
 50         if(o==0) adeg(S,x,dem[o][x]-n,0);
 51         else adeg(x+N,T,dem[o][x]-n,0);
 52         return dem[o][x];
 53     }return n;
 54 }
 55 
 56 queue<int> q;
 57 int dis[maxn*2],ine[maxn*2];
 58 bool flag[maxn*2];
 59 
 60 inline bool spfa(){
 61     CLR(dis,-127);dis[S]=0;
 62     CLR(ine,0);q.push(S);
 63     while(!q.empty()){
 64         int p=q.front();q.pop();
 65         flag[p]=0;
 66         for(int i=egh[p];i;i=eg[i].ne){
 67             int b=eg[i].b;if(!eg[i].l) continue;
 68             if(dis[b]<dis[p]+eg[i].c){
 69                 dis[b]=dis[p]+eg[i].c,ine[b]=i;
 70                 if(!flag[b]) q.push(b),flag[b]=1;
 71             }
 72         }
 73     }return dis[T]>=-1e9;
 74 }
 75 
 76 int main(){
 77     //freopen("","r",stdin);
 78     int i,j,k;
 79     N=rd(),rt[0]=rd(),rt[1]=rd();
 80     for(i=1;i<=N;i++)
 81         val[i]=rd();
 82     for(i=1;i<N;i++) adteg(0,rd(),rd());
 83     for(i=1;i<N;i++) adteg(1,rd(),rd());
 84     for(i=rd();i;i--){
 85         int x=rd(),y=rd();
 86         dem[0][x]=y;
 87     }for(i=rd();i;i--){
 88         int x=rd(),y=rd();
 89         dem[1][x]=y;
 90     }
 91     dfs(0,rt[0],0,0);dfs(1,rt[1],0,0);
 92     for(i=1;i<=N;i++){
 93         adeg(cfa[0][i],cfa[1][i]+N,1,val[i]);
 94     }
 95     if(inl!=outl) ext();
 96     int ans=0;
 97     while(spfa()){
 98         int mi=1e9;
 99         for(i=T;i!=S;i=eg[ine[i]^1].b){
100             mi=min(mi,eg[ine[i]].l);
101         }ans+=mi*dis[T];
102         inl-=mi;
103         for(i=T;i!=S;i=eg[ine[i]^1].b){
104             eg[ine[i]].l-=mi,eg[ine[i]^1].l+=mi;
105         }
106     }
107     if(inl) ext();
108     printf("%d\n",ans);
109     return 0;
110 }

 

cf1061E Politics (费用流)

标签:return   ons   spfa   empty   std   lin   完全   i++   name   

原文地址:https://www.cnblogs.com/Ressed/p/10050708.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!