zoukankan      html  css  js  c++  java
  • 【CodeForces】【311E】Biologist

    网络流/最大权闭合图


      题目:http://codeforces.com/problemset/problem/311/E

      嗯这是最大权闭合图中很棒的一道题了~

      能够1A真是开心~也是我A掉的第一道E题吧……(其实是这题放在E偏水了吧……)

      题目大意:有n个0/1变量,给定每个变量的初值,以及每个变量取反的费用$v_i$,有m组需求,对于第 i 组需求,如果集合$S_i$里面的每个变量的值都为给定的v(0 or 1),则获得$omega_i$的利润,求最大总利润。(其中某些请求若是无法满足还需额外付出g的代价)

      这题其实用的思路有点类似最小割……假定跟S相连的变量是选1,跟T相连的是选0,那么对于初值为1的点连i->T,容量为$v_i$,初值为0的连S->i,容量为$v_i$,表示将这些变量取反的代价。

      然后考虑需求,如果是要求全为1,则对每个$S_i$中的元素$i$连边 i->n+j ,费用为INF,同时连n+j->T,容量为$omega_i$;如果是全为0的请求则反过来。

      另外这题有个特殊的要求:一些无法满足的请求需要额外付出g的代价。其实这很好解决,我们的答案是$sum omega_i-max_flow$,那么我们对于“朋友的请求”,就在tot+了$omega_i$后,建边时改成容量为$omega_i+g$即可。

    #WhenWhoProblemLangVerdictTimeMemory
    10516710 2015-03-29 17:21:31 Tunix E - Biologist GNU C++ Accepted 92 ms 28188 KB
     1 //CF 311E
     2 #include<vector>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cstdlib>
     6 #include<iostream>
     7 #include<algorithm>
     8 #define rep(i,n) for(int i=0;i<n;++i)
     9 #define F(i,j,n) for(int i=j;i<=n;++i)
    10 #define D(i,j,n) for(int i=j;i>=n;--i)
    11 #define pb push_back
    12 using namespace std;
    13 inline int getint(){
    14     int v=0,sign=1; char ch=getchar();
    15     while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
    16     while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
    17     return v*sign;
    18 }
    19 const int N=1e6+10,M=400020,INF=~0u>>2;
    20 typedef long long LL;
    21 /******************tamplate*********************/
    22 int n,m,g,tot,ans;
    23 int a[N],v[N];
    24 struct edge{int to,v;};
    25 struct Net{
    26     edge E[M];
    27     int head[N],next[M],cnt;
    28     void ins(int x,int y,int v){
    29         E[++cnt]=(edge){y,v};
    30         next[cnt]=head[x]; head[x]=cnt;
    31     }
    32     void add(int x,int y,int v){
    33         ins(x,y,v); ins(y,x,0);
    34     }
    35     int S,T,cur[N],d[N],Q[N];
    36     bool mklevel(){
    37         memset(d,-1,sizeof d);
    38         d[S]=0;
    39         int l=0,r=-1;
    40         Q[++r]=S;
    41         while(l<=r){
    42             int x=Q[l++];
    43             for(int i=head[x];i;i=next[i])
    44                 if (d[E[i].to]==-1 && E[i].v){
    45                     d[E[i].to]=d[x]+1;
    46                     Q[++r]=E[i].to;
    47                 }
    48         }
    49         return d[T]!=-1;
    50     }
    51     int dfs(int x,int a){
    52         if (x==T) return a;
    53         int flow=0;
    54         for(int &i=cur[x];i && flow<a;i=next[i])
    55             if (E[i].v && d[E[i].to]==d[x]+1){
    56                 int f=dfs(E[i].to,min(a-flow,E[i].v));
    57                 E[i].v-=f;
    58                 E[i^1].v+=f;
    59                 flow+=f;
    60             }
    61         if (!flow) d[x]=-1;
    62         return flow;
    63     }
    64     void Dinic(){
    65         while(mklevel()){ 
    66             F(i,S,T) cur[i]=head[i];
    67             ans+=dfs(S,INF);
    68         }
    69     }
    70     void init(){
    71         n=getint(); m=getint(); g=getint();
    72         F(i,1,n) a[i]=getint();
    73         F(i,1,n) v[i]=getint();
    74         cnt=1; S=0; T=n+m+1; ans=tot=0;
    75         F(i,1,n) if(a[i]) add(S,i,v[i]);else add(i,T,v[i]);
    76         F(i,1,m){
    77             int x=getint(), w=getint(), k=getint(); tot+=w;
    78             F(j,1,k){
    79                 int y=getint();
    80                 if (!x) add(y,n+i,INF);
    81                 else add(n+i,y,INF);
    82             }
    83             int y=getint();
    84             if(y) w+=g;//if friend
    85             if (!x) add(n+i,T,w);
    86             else add(S,n+i,w);
    87         }
    88     }
    89 }G1;
    90 
    91 int main(){
    92 #ifndef ONLINE_JUDGE
    93     freopen("311E.in","r",stdin);
    94     freopen("311E.out","w",stdout);
    95 #endif
    96     G1.init(); G1.Dinic();
    97     printf("%d
    ",tot-ans);
    98     return 0;
    99 }
    View Code

      

  • 相关阅读:
    Vue.js进阶知识点总结
    测试初学
    gitee简单命令使用
    Ubuntu学习之alias命令
    Python turtle.right与turtle.setheading的区别
    Python-对Pcap文件进行处理,获取指定TCP流
    第八次作业
    第七次作业
    第八周作业
    第七周作业
  • 原文地址:https://www.cnblogs.com/Tunix/p/4376622.html
Copyright © 2011-2022 走看看