SGU 194 Reactor Cooling

http://acm.sgu.ru/problem.php?contest=0&problem=194

题意:m条有向边,有上下界,求最大流。

思路:原图中有u-v low[i],high[i] 建图就是u->v,high[i]-low[i],同时du[u]-=low[i],du[v]+=low[i],然后对于每个点i,如果du[i]>0,那就S->i,du[i],若是du[i]<0那就i->T ,-du[i],然后判断S出去的流是不是满流,不是就无解,否则每条边流量就是基础流量再加上附加流。

啊♂,一开始脑抽了,反向边流量忘记变成0了。。

 1 #include<algorithm>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<iostream>
 6 #define inf 0x7fffffff
 7 int S,T,nodes;
 8 int id[200005];
 9 int tot,go[200005],next[200005],dn[200005],first[200005],flow[200005];
10 int dis[200005],cnt[200005],op[200005],ans[200005],du[200005],n,m;
11 int read(){
12     char ch=getchar();int t=0,f=1;
13     while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
14     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
15     return t*f;
16 }
17 void insert(int x,int y,int z,int Id){
18     tot++;
19     go[tot]=y;
20     next[tot]=first[x];
21     first[x]=tot;
22     flow[tot]=z;
23     id[tot]=Id;
24 }
25 void add(int x,int y,int z,int Id){
26     insert(x,y,z,Id);op[tot]=tot+1;
27     insert(y,x,0,0);op[tot]=tot-1;
28 }
29 int dfs(int x,int f){
30     if (x==T) return f;
31     int mn=nodes,sum=0;
32     for (int i=first[x];i;i=next[i]){
33         int pur=go[i];
34         if (flow[i]&&dis[pur]+1==dis[x]){
35             int save=dfs(pur,std::min(f-sum,flow[i]));
36             sum+=save;
37             flow[i]-=save;
38             flow[op[i]]+=save;
39             if (dis[S]>=nodes||f==sum) return sum;
40         }
41         if (flow[i]) mn=std::min(mn,dis[pur]);
42     }
43     if (sum==0){
44         cnt[dis[x]]--;
45         if (cnt[dis[x]]==0)
46          dis[S]=nodes;
47         else
48          dis[x]=mn+1,cnt[dis[x]]++; 
49     }
50     return sum;
51 }
52 int main(){
53     while (~scanf("%d%d",&n,&m)){
54         for (int i=0;i<=n+2;i++) dis[i]=cnt[i]=first[i]=du[i]=0;
55         tot=0;S=0;T=n+1;nodes=T+1;
56         for (int i=1;i<=m;i++){
57             int u=read(),v=read(),lf=read(),hf=read();
58             add(u,v,hf-lf,i);
59             du[u]-=lf;
60             du[v]+=lf;
61             dn[i]=lf;
62         }
63         for (int i=1;i<=n;i++){
64             if (du[i]>0) add(S,i,du[i],0);
65             if (du[i]<0) add(i,T,-du[i],0);
66         }
67         int Ans;
68         while (dis[S]<nodes) Ans+=dfs(S,inf);
69         bool flag=true;
70         for (int i=first[S];i;i=next[i])
71          if (flow[i]!=0){
72                 flag=false;
73                 break;
74          }
75         if (!flag) {
76             puts("NO");
77             continue;
78         }else{
79             puts("YES");
80             for (int i=1;i<=tot;i++) ans[id[i]]=flow[op[i]];
81             for (int i=1;i<=m;i++) printf("%d
",dn[i]+ans[i]);
82         }
83     }
84 }
原文地址:https://www.cnblogs.com/qzqzgfy/p/5618644.html