有上下界的网络流问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了有上下界的网络流问题相关的知识,希望对你有一定的参考价值。

这个博客写的不错:http://www.cnblogs.com/kane0526/archive/2013/04/05/3001108.html

sgu194 Reactor Cooling

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 using namespace std;
 7 char ch;
 8 bool ok;
 9 void read(int &x){
10     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch==-) ok=1;
11     for (x=0;isdigit(ch);x=x*10+ch-0,ch=getchar());
12     if (ok) x=-x;
13 }
14 const int maxn=205;
15 const int maxm=maxn*maxn;
16 const int inf=1061109567;
17 int n,m,a,b,c,d;
18 struct flow{
19     int tot,id,s,t,maxflow,now[maxn],son[maxm],pre[maxm],val[maxm],down[maxm],up[maxm],sum[maxn];
20     int head,tail,que[maxn],dis[maxn];
21     bool bo[maxn];
22     void init(){tot=1,s=0,t=n+1,memset(now,0,sizeof(now));}
23     void put(int a,int b,int c){pre[++tot]=now[a],now[a]=tot,son[tot]=b,val[tot]=c;}
24     void add(int a,int b,int c){put(a,b,c),put(b,a,0);}
25     void add(int a,int b,int c,int d){down[++id]=c,up[id]=d,sum[a]-=c,sum[b]+=c,add(a,b,d-c);}
26     void prepare(){
27         for (int i=1;i<=n;i++) if (sum[i]>0) add(s,i,sum[i]),maxflow+=sum[i]; else add(i,t,-sum[i]);
28     }
29     bool bfs(){
30         memset(bo,0,sizeof(bo));
31         memset(dis,0,sizeof(dis));
32         head=0,tail=1,que[1]=s,bo[s]=1;
33         while (head<tail){
34             int u=que[++head];
35             for (int p=now[u],v=son[p];p;p=pre[p],v=son[p])
36                 if (val[p]&&!bo[v]) bo[v]=1,dis[v]=dis[u]+1,que[++tail]=v;
37         }
38         return bo[t];
39     }
40     int dfs(int u,int rest){
41         if (u==t) return rest;
42         int ans=0;
43         for (int p=now[u],v=son[p];p&&rest;p=pre[p],v=son[p])
44             if (val[p]&&dis[v]==dis[u]+1){
45                 int d=dfs(v,min(rest,val[p]));
46                 val[p]-=d,val[p^1]+=d,rest-=d,ans+=d;
47             }
48         if (!ans) dis[u]=-1;
49         return ans;
50     }
51     int dinic(){
52         int ans=0;
53         while (bfs()) ans+=dfs(s,inf);
54         return ans;
55     }
56     void work(){
57         if (maxflow!=dinic()){puts("NO");return;}
58         puts("YES");
59         for (int i=1;i<=m;i++) printf("%d\\n",val[(i<<1)+1]+down[i]);
60     }
61 }f;
62 int main(){
63     read(n),read(m),f.init();
64     for (int i=1;i<=m;i++) read(a),read(b),read(c),read(d),f.add(a,b,c,d);
65     f.prepare(),f.work();
66     return 0;
67 }

zoj3229 Shoot the Bullet

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 using namespace std;
 7 char ch;
 8 bool ok;
 9 void read(int &x){
10     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch==-) ok=1;
11     for (x=0;isdigit(ch);x=x*10+ch-0,ch=getchar());
12     if (ok) x=-x;
13 }
14 const int maxn=1400;
15 const int maxm=740000;
16 const int inf=1061109567;
17 int n,m,a,b,c,d,x,y;
18 bool flag[maxm];
19 struct flow{
20     int s[2],t[2],tot,id,now[maxn],son[maxm],pre[maxm],val[maxm],down[maxm],sum[maxn];
21     int head,tail,que[maxn],dis[maxn];
22     bool bo[maxn];
23     void init(){s[0]=0,t[0]=n+m+1,s[1]=n+m+2,t[1]=n+m+3,tot=1,id=0,memset(now,0,sizeof(now)),memset(sum,0,sizeof(sum));}
24     void put(int a,int b,int c){pre[++tot]=now[a],now[a]=tot,son[tot]=b,val[tot]=c;}
25     void add(int a,int b,int c){put(a,b,c),put(b,a,0);}
26     void add(int a,int b,int c,int d){sum[a]-=c,sum[b]+=c,down[++id]=c,add(a,b,d-c);}
27     bool bfs(int op){
28         memset(bo,0,sizeof(bo));
29         memset(dis,0,sizeof(dis));
30         head=0,tail=1,bo[s[op]]=1,que[1]=s[op];
31         while (head<tail){
32             int u=que[++head];
33             for (int p=now[u],v=son[p];p;p=pre[p],v=son[p])
34                 if (val[p]&&!bo[v]){
35                     if (!op&&(v==s[1]||v==t[1]||(p>>1)==id+1)) continue;
36                     bo[v]=1,dis[v]=dis[u]+1,que[++tail]=v;
37                 }
38         }
39         return bo[t[op]];
40     }
41     int dfs(int u,int rest,int op){
42         if (u==t[op]) return rest;
43         int ans=0;
44         for (int p=now[u],v=son[p];p&&rest;p=pre[p],v=son[p])
45             if (val[p]&&dis[v]==dis[u]+1){
46                 if (!op&&(v==s[1]||v==t[1]||(p>>1)==id+1)) continue;
47                 int d=dfs(v,min(val[p],rest),op);
48                 val[p]-=d,val[p^1]+=d,ans+=d,rest-=d;
49             }
50         if (!ans) dis[u]=-1;
51         return ans;
52     }
53     int dinic(int op){
54         int ans=0;
55         while (bfs(op)) ans+=dfs(s[op],inf,op);
56         return ans;
57     }
58     void work(){
59         add(t[0],s[0],inf);
60         int maxflow=0;
61         for (int i=s[0];i<=t[0];i++) if (sum[i]>0) add(s[1],i,sum[i]),maxflow+=sum[i]; else add(i,t[1],-sum[i]);
62         if (dinic(1)!=maxflow){puts("-1");return;}
63         maxflow+=dinic(0);
64         printf("%d\\n",maxflow);
65         for (int i=1;i<=id;i++) if (flag[i]) printf("%d\\n",val[(i<<1)+1]+down[i]);
66     }
67 }f;
68 int main(){
69     while (~scanf("%d%d",&n,&m)){
70         f.init(),memset(flag,0,sizeof(flag));
71         for (int i=1;i<=m;i++) scanf("%d",&x),f.add(i+n,f.t[0],x,inf);
72         for (int i=1;i<=n;i++){
73             scanf("%d%d",&c,&d),f.add(f.s[0],i,0,d);
74             while (c--) scanf("%d%d%d",&a,&x,&y),a++,f.add(i,a+n,x,y),flag[f.id]=1;
75         }
76         f.work(),puts("");
77     }
78     return 0;
79 }

sgu176  Flow construction

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 using namespace std;
 7 char ch;
 8 bool ok;
 9 void read(int &x){
10     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch==-) ok=1;
11     for (x=0;isdigit(ch);x=x*10+ch-0,ch=getchar());
12     if (ok) x=-x;
13 }
14 const int maxn=105;
15 const int maxm=maxn*maxn;
16 const int inf=1061109567;
17 int n,m,a,b,c,d;
18 struct flow{
19     int s[2],t[2],tot,id,now[maxn],son[maxm],pre[maxm],val[maxm],down[maxm],sum[maxn];
20     int head,tail,que[maxn],dis[maxn];
21     bool bo[maxn];
22     void init(){s[0]=1,t[0]=n,s[1]=0,t[1]=n+1,tot=1,id=0,memset(now,0,sizeof(now)),memset(sum,0,sizeof(sum));}
23     void put(int a,int b,int c){pre[++tot]=now[a],now[a]=tot,son[tot]=b,val[tot]=c;}
24     void add(int a,int b,int c){put(a,b,c),put(b,a,0);}
25     void add(int a,int b,int c,int d){sum[a]-=c,sum[b]+=c,down[++id]=c,add(a,b,d-c);}
26     bool bfs(){
27         memset(bo,0,sizeof(bo));
28         memset(dis,0,sizeof(dis));
29         head=0,tail=1,que[1]=s[1],bo[s[1]]=1;
30         while (head<tail){
31             int u=que[++head];
32             for (int p=now[u],v=son[p];p;p=pre[p],v=son[p])
33                 if (val[p]&&!bo[v]) bo[v]=1,dis[v]=dis[u]+1,que[++tail]=v;
34         }
35         return bo[t[1]];
36     }
37     int dfs(int u,int rest){
38         if (u==t[1]) return rest;
39         int ans=0;
40         for (int p=now[u],v=son[p];p&&rest;p=pre[p],v=son[p])
41             if (val[p]&&dis[v]==dis[u]+1){
42                 int d=dfs(v,min(rest,val[p]));
43                 val[p]-=d,val[p^1]+=d,ans+=d,rest-=d;
44             }
45         if (!ans) dis[u]=-1;
46         return ans;
47     }
48     int dinic(){
49         int ans=0;
50         while (bfs()) ans+=dfs(s[1],inf);
51         return ans;
52     }
53     void work(){
54         int maxflow=0,res=0;
55         for (int i=s[0];i<=t[0];i++) if (sum[i]>0) maxflow+=sum[i],add(s[1],i,sum[i]); else add(i,t[1],-sum[i]);
56         res+=dinic(),add(t[0],s[0],inf),res+=dinic();
57         if (res!=maxflow){puts("Impossible");return;}
58         printf("%d\\n",val[tot]);
59         for (int i=1;i<=m;i++) printf("%d%c",val[(i<<1)+1]+down[i],i==m?\\n: );
60     }
61 }f;
62 int main(){
63     read(n),read(m),f.init();
64     for (int i=1;i<=m;i++){
65         read(a),read(b),read(c),read(d);
66         if (d) f.add(a,b,c,c); else f.add(a,b,0,c);
67     }
68     f.work();
69     return 0;
70 }

 

以上是关于有上下界的网络流问题的主要内容,如果未能解决你的问题,请参考以下文章

Cogs 12 运输问题2 (有上下界网络流)

ZOJ 3496 Assignment | 二分+有上下界网络流

有上下界的有多组源汇的网络流费用流问题

有上下界网络流

BZOJ 2406 二分+有上下界的网络流判定

有上下界限制的网络流