zoukankan      html  css  js  c++  java
  • cf1061E Politics (费用流)

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

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

    那么我用一个点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
    ");
     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
    ",ans);
    109     return 0;
    110 }
  • 相关阅读:
    拉格朗日乘子法
    EM算法
    最大似然估计
    理解先验概率 后验概率 似然函数
    似然函数理解
    markdown 语法规则
    bash101总结
    hmm和Veterbi算法(一)
    Kaldi 安装
    通俗的解释交叉熵与相对熵
  • 原文地址:https://www.cnblogs.com/Ressed/p/10050708.html
Copyright © 2011-2022 走看看