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 }

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

时间: 2024-10-13 00:08:25

ZOJ3229 Shoot the Bullet的相关文章

ZOJ3229 Shoot the Bullet(有源汇的上下界最大流)

#pragma warning(disable:4996) #include <iostream> #include <cstring> #include <string> #include <vector> #include <cstdio> #include <algorithm> #include <cmath> #include <queue> #include <map> #include

ZOJ3229 Shoot the Bullet(有源汇流量有上下界网络的最大流)

题目大概说在n天里给m个女孩拍照,每个女孩至少要拍Gi张照片,每一天最多拍Dk张相片且都有Ck个拍照目标,每一个目标拍照的张数要在[Lki, Rki]范围内,问最多能拍几张照片. 源点-天-女孩-汇点,这样子建容量网络.然后就是求这个有源汇流量有上下界容量网络的最大流: 首先计算其可行流,POJ2396 然后删除附加源.附加汇以及汇点到源点容量INF的边 最后从源点到汇点跑一边最大流即可 1 #include<cstdio> 2 #include<cstring> 3 #inclu

ZOJ 3229 Shoot the Bullet

有源点汇点的上下界最大流问题... 建图很简单...按题意即可... 设原图 源点为 s 汇点 为 t,连一条t到s无下界上界无限大的边....设两个超级源S,T,像无源汇判断可行流的问题一样,记录每个点的in,连接到相应的超级源汇点...对S,T跑一遍最大流,并检测S所连边是否满流...如果不满足连可行流都没有无解...否则去掉S,T点(但总点数不要边...在这里错了一下午)对s,t跑一遍最大流.得到的结果既答案.....第一遍最大流保证了每个点的下界流得到满足,此时的图里还有很多自由流可以走

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

题目:ZOJ Problem Set - 3229 Shoot the Bullet 分类:有源有汇有上下界网络流 题意:有 n 天和 m 个girls,然后每天给一部分girls拍照,每个girls 有拍照的下限,即最少要拍这么多张,然后每天有k个女孩拍照,摄影师最多可以拍num张,然后 k 个女该每天拍照数量值有上下限,然后问你有没有满足这样条件的给女孩拍照的最大方案,然后按照输入输出每天给女孩拍照的张数. 做这道题目推荐先做:这儿 分析:首先它让你判断能不能满足条件. 按照题目给出的条件很

ZOJ 3229 Shoot the Bullet 有源有汇带下界的最大流

链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3229 Shoot the Bullet Time Limit: 2 Seconds      Memory Limit: 32768 KB      Special Judge Gensokyo is a world which exists quietly beside ours, separated by a mystical border. It is a u

ZOJ 3229 Shoot the Bullet 无源汇上下界最大流

Shoot the Bullet Time Limit: 2 Seconds      Memory Limit: 32768 KB      Special Judge Gensokyo is a world which exists quietly beside ours, separated by a mystical border. It is a utopia where humans and other beings such as fairies, youkai(phantoms)

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

ZOJ 3229 Shoot the Bullet 链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3229 题意:一个屌丝给m个女神拍照,计划拍照n天,每一天屌丝最多给C个女神拍照,每天拍照数不能超过D张,而且给每个女神 i 拍照有数量限制[Li,Ri],对于每个女神n天的拍照总和不能超过Gi,如果有解求屌丝最多能拍多少张照,并求每天给对应女神拍多少张照:否则输出-1. 思路: 有源汇有上下界的最大流 1. 在原先

Shoot the Bullet

zoj3229:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3442 题意:一个摄影师,在n天内给m个女神拍照.每个女神至少要拍Gi张照片,每一天只能给Ci个女神照相,每一天只能只能拍Di张照片,并且每个女神每天被拍的数量在[l,r]之间.问是否存在一种方案,满足条件,如果满足,最多可以照多少照片. 题解:这是一条有源汇的有上下界的最大流.首先源点s,t,源点和每一天i建立一边,上界为Di,下界为0,每个女神和t建立一边,

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

Shoot the Bullethttp://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3442 Time Limit: 2 Seconds      Memory Limit: 32768 KB      Special Judge Gensokyo is a world which exists quietly beside ours, separated by a mystical border. It is a utopia