zoukankan      html  css  js  c++  java
  • ZOJ3229 Shoot the Bullet

    http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=20756

    思路:就讲一下有源汇上下界最大流的做法吧!对于所有的边,就按照无源汇的做法做,然后建一条(t->s,inf)的边,然后先算ss到tt的最大流,看是否满足下界,然后不管这个流的答案,清空cnt和dis,然后算出s->t的最大流,就是答案。

     1 #include<cstdio>
     2 #include<cmath>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<cstring>
     6 #define inf 0x7fffffff
     7 int dn[200005],id[200005];
     8 int tot,go[1000005],next[1000005],first[200005],flow[1000005];
     9 int n,m,du[200005],op[1000005],cnt[200005],dis[200005];
    10 int read(){
    11     int t=0,f=1;char ch=getchar();
    12     while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
    13     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
    14     return t*f;
    15 }
    16 void insert(int x,int y,int z){
    17     tot++;
    18     go[tot]=y;
    19     next[tot]=first[x];
    20     first[x]=tot;
    21     flow[tot]=z;
    22 }
    23 void add(int x,int y,int z){
    24     insert(x,y,z);op[tot]=tot+1;
    25     insert(y,x,0);op[tot]=tot-1;
    26 }
    27 int dfs(int x,int f,int S,int T,int nodes){
    28     int mn=nodes,sum=0;
    29     if (x==T) return f;
    30     for (int i=first[x];i;i=next[i]){
    31       int pur=go[i];
    32       if (flow[i]&&dis[pur]+1==dis[x]){
    33         int F=std::min(flow[i],f-sum);
    34         int save=dfs(pur,F,S,T,nodes);
    35         sum+=save;
    36         flow[i]-=save;
    37         flow[op[i]]+=save;
    38         if (sum==f||dis[S]>=nodes) return sum;
    39       }
    40       if (flow[i]) mn=std::min(mn,dis[pur]);
    41     }
    42     if (sum==0){
    43       cnt[dis[x]]--;
    44     if (cnt[dis[x]]==0){
    45       dis[S]=nodes;
    46     }else{
    47       dis[x]=mn+1;
    48       cnt[dis[x]]++;
    49       }
    50     }
    51     return sum;
    52 }
    53 int mxflow(int S,int T,int nodes){
    54     int res=0;
    55     for (int i=0;i<=nodes;i++) cnt[i]=dis[i]=0;
    56     while (dis[S]<nodes) 
    57       res+=dfs(S,inf,S,T,nodes);
    58     return res;
    59 }
    60 int main(){
    61     freopen("tx.in","r",stdin);
    62     int Nodes=0;
    63     while (~scanf("%d%d",&n,&m)){
    64       for (int i=0;i<=Nodes;i++) first[i]=du[i]=0;tot=0;
    65       int s=n+m+1,t=s+1;
    66       int ss=t+1,tt=ss+1;
    67       for (int i=1;i<=m;i++){
    68        int x=read();
    69        du[i]-=x;
    70        du[t]+=x;
    71        add(i,t,inf);
    72       }
    73      int Cnt=0;
    74      for (int i=1;i<=n;i++){
    75      int c=read(),d=read();
    76      add(s,i+m,d);
    77      while (c--){
    78        int x=read(),l=read(),r=read();
    79        du[i+m]-=l;
    80        du[x+1]+=l;
    81        dn[++Cnt]=l;id[Cnt]=tot+1;
    82        add(i+m,x+1,r-l);
    83      }
    84      }
    85      int sum=0;
    86      for (int i=1;i<=t;i++)
    87      if (du[i]>0) add(ss,i,du[i]),sum+=du[i];
    88      else add(i,tt,-du[i]);
    89      add(t,s,inf); 
    90      if (sum!=mxflow(ss,tt,tt)) puts("-1");
    91      else{
    92       printf("%d
    ",mxflow(s,t,tt));
    93      for (int i=1;i<=Cnt;i++) 
    94       printf("%d
    ",dn[i]+flow[op[id[i]]]);
    95      }
    96      puts("");
    97      Nodes=tt;
    98     }
    99 }

    **,没看到可能有多解,害我调了好久。。

  • 相关阅读:
    自然语言交流系统 phxnet团队 创新实训 项目博客 (十一)
    install ubuntu on Android mobile phone
    Mac OS, Mac OSX 与Darwin
    About darwin OS
    自然语言交流系统 phxnet团队 创新实训 项目博客 (十)
    Linux下编译安装qemu和libvirt
    libvirt(virsh命令总结)
    深入浅出 kvm qemu libvirt
    自然语言交流系统 phxnet团队 创新实训 项目博客 (九)
    自然语言交流系统 phxnet团队 创新实训 项目博客 (八)
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5620782.html
Copyright © 2011-2022 走看看