ZOJ3229 Shoot the Bullet

Posted GFY

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n",mxflow(s,t,tt));
93      for (int i=1;i<=Cnt;i++) 
94       printf("%d\n",dn[i]+flow[op[id[i]]]);
95      }
96      puts("");
97      Nodes=tt;
98     }
99 }

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

以上是关于ZOJ3229 Shoot the Bullet的主要内容,如果未能解决你的问题,请参考以下文章

ZOJ3229 Shoot the Bullet

zoj 3229 Shoot the Bullet(有源汇上下界最大流)

ZOJ3229:Shoot the Bullet——题解

ZOJ Problem Set - 3229 Shoot the Bullet 有上下界网络流+流量输出

ZOJ 3229 Shoot the Bullet (有源有汇有上下界最大流)

有上下界的网络流2-有源汇带上下界网络流ZOJ3229