SGU176 Flow construction

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

有源汇上下界最小流,可以选择跟有源汇上下界最大流一样的建图方式,然后用二分去二分t->s这条边的流量,最小的可行流就是答案。

也可以这样:

跟无源汇最大流建图一样,然后不添加t->s的边

对ss->tt求最大流,然后添加t->s的边,求ss->tt最大流,若是满流,则t->s的流量就是最小流

PS:记录一下:SGU的ID是068720

第二种建图方式:

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<iostream>
 6 #define inf 0x7fffffff
 7 const int maxn=110;
 8 const int maxe=maxn*maxn+10;
 9 int tot,go[maxe],first[maxn],next[maxe],flow[maxe];
10 int op[maxe],id[maxe],n,m,du[maxn],cnt[maxn],dis[maxn];
11 int dn[maxe];
12 int read(){
13     int t=0,f=1;char ch=getchar();
14     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
15     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
16     return t*f;
17 }
18 void insert(int x,int y,int z){
19     tot++;
20     go[tot]=y;
21     next[tot]=first[x];
22     first[x]=tot;
23     flow[tot]=z;
24 }
25 void add(int x,int y,int z){
26     insert(x,y,z);op[tot]=tot+1;
27     insert(y,x,0);op[tot]=tot-1;
28 }
29 int dfs(int x,int f,int S,int T,int nodes){
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 F=std::min(f-sum,flow[i]);
36             int save=dfs(pur,F,S,T,nodes);
37             flow[i]-=save;
38             flow[op[i]]+=save;
39             sum+=save;
40             if (f==sum||dis[S]>=nodes) return sum;
41         }
42         if (flow[i]) mn=std::min(mn,dis[pur]);
43     }
44     if (sum==0){
45         cnt[dis[x]]--;
46         if (cnt[dis[x]]==0) dis[S]=nodes;
47         else {
48             dis[x]=mn+1;
49             cnt[dis[x]]++;
50         }
51     }
52     return sum;
53 }
54 int mxflow(int S,int T,int nodes){
55     int res=0;
56     for (int i=0;i<=nodes;i++) cnt[i]=dis[i]=0;
57     while (dis[S]<nodes) res+=dfs(S,inf,S,T,nodes);
58     return res;
59 }
60 int main(){
61     int s,t;
62     n=read();m=read();
63     s=0;t=n+1;
64     for (int i=1;i<=m;i++){
65           int u=read(),v=read(),c=read(),pd=read();
66           if (pd){
67             du[u]-=c;
68             du[v]+=c;
69             add(u,v,0);
70             dn[i]=c;id[i]=tot;
71           }else{
72             add(u,v,c);
73             dn[i]=0;id[i]=tot;
74           }
75     }
76     int sum=0;
77     for (int i=1;i<=n;i++)
78         if (du[i]<0) add(i,t,-du[i]);
79             else add(s,i,du[i]),sum+=du[i];
80     int sum1=mxflow(s,t,t+1);
81     add(n,1,inf);
82     int sum2=mxflow(s,t,t+1);
83     int sx=0;
84     for (int i=first[s];i;i=next[i]){
85          if (flow[i]){
86          puts("Impossible");
87          return 0;
88          }
89     }
90     printf("%d
",flow[tot]);
91     for (int i=1;i<=m;i++)
92         printf("%d ",flow[id[i]]+dn[i]);
93         
94     return 0;
95 }
原文地址:https://www.cnblogs.com/qzqzgfy/p/5621466.html