[loj#115] 无源汇有上下界可行流 网络流

Posted wls001

tags:

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

#115. 无源汇有上下界可行流

内存限制:256 MiB时间限制:1000 ms标准输入输出
题目类型:传统评测方式:Special Judge
上传者: 匿名

题目描述

这是一道模板题。

n nn 个点,m mm 条边,每条边 e ee 有一个流量下界 lower(e) \text{lower}(e)lower(e) 和流量上界 upper(e) \text{upper}(e)upper(e),求一种可行方案使得在所有点满足流量平衡条件的前提下,所有边满足流量限制。

输入格式

第一行两个正整数 n nn、m mm。

之后的 m mm 行,每行四个整数 s ss、t tt、lower \text{lower}lower、upper \text{upper}upper。

输出格式

如果无解,输出一行 NO

否则第一行输出 YES,之后 m mm 行每行一个整数,表示每条边的流量。

样例

样例输入 1

4 6
1 2 1 2
2 3 1 2
3 4 1 2
4 1 1 2
1 3 1 2
4 2 1 2

样例输出 1

NO

样例输入 2

4 6
1 2 1 3
2 3 1 3
3 4 1 3
4 1 1 3
1 3 1 3
4 2 1 3

样例输出 2

YES
1
2
3
2
1
1

数据范围与提示

1≤n≤200,1≤m≤10200 1 \leq n \leq 200, 1 \leq m \leq 102001n200,1m10200

 

技术分享图片
 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<algorithm>
 7 #define maxm 12000
 8 #define maxn 500
 9 using namespace std;
10 int read() {
11     int x=0,f=1;char ch=getchar();
12     while(!isdigit(ch)){ch=getchar();}
13     while(isdigit(ch)){x=x*10+ch-0;ch=getchar();}
14     return x;
15 }
16 struct data {
17     int to,next,w,f;
18 }e[maxm*16];
19 int head[maxn],cnt;
20 int cur[maxn];
21 void add(int u,int v,int w,int f){e[cnt].next=head[u];e[cnt].to=v;e[cnt].w=w;e[cnt].f=f;head[u]=cnt++;}
22 int n,m,s,t;
23 int q[maxn];
24 bool vis[maxn];
25 int dis[maxn];
26 bool bfs() {
27     memset(dis,-97,sizeof(dis));
28     int h=0,tt=1;
29     q[h]=t;
30     vis[t]=1;
31     dis[t]=0;
32     while(h!=tt) {
33         int now=q[h];h++;vis[now]=0;if(h==maxn) h=0;
34         for(int i=head[now];i>=0;i=e[i].next) {
35             int to=e[i].to;
36             if(e[i^1].w&&dis[to]<-1000000) {
37                 dis[to]=dis[now]-1;
38                 if(!vis[to]){
39                     vis[to]=1;
40                     q[tt++]=to;if(tt==maxn) tt=0;
41                 }
42             }
43         }
44     }
45     return dis[s]>=-1000000;
46 }
47 int dfs(int now,int a) {
48     if(now==t||a==0) return a;
49     int flow=0,f;
50     for(int i=cur[now];i>=0;i=e[i].next) {
51         int to=e[i].to;
52         if(dis[to]==dis[now]+1&&e[i].w>0&&(f=dfs(to,min(a,e[i].w)))) {
53             e[i].w-=f;
54             e[i^1].w+=f;
55             flow+=f;
56             a-=f;
57             if(a==0) return flow;
58         }
59         cur[now]=i;
60     }
61     if(!flow) dis[now]=-1;
62     return flow;
63 }
64 int main() {
65     memset(head,-1,sizeof(head));
66     n=read(),m=read(),s=0,t=n+1;
67     int tot=0;
68     for(int i=1;i<=m;i++) {
69         int u=read(),v=read(),lw=read(),w=read();
70         tot+=lw;
71         add(u,v,w-lw,w);add(v,u,0,0);
72         add(0,v,lw,lw);add(v,0,0,lw);
73         add(u,n+1,lw,lw);add(n+1,u,0,0);
74     }
75     int ans=0;
76     while(bfs()){
77         for(int i=0;i<=n+1;i++) cur[i]=head[i];
78         ans+=dfs(s,2147483647);
79     }
80     if(ans==tot) {
81         printf("YES\n");
82         for(int i=0;i<m*6;i+=6) {printf("%d\n",e[i].f-e[i].w);}
83         return 0;
84     }
85     printf("NO\n");
86 }
View Code

 

以上是关于[loj#115] 无源汇有上下界可行流 网络流的主要内容,如果未能解决你的问题,请参考以下文章

loj#115. 无源汇有上下界可行流

(一道模板题) 无源汇有上下界可行流

ZOJ 2314 Reactor Cooling(无源汇有上下界可行流)

网络流进阶

与网络流相关算法

SGU 194 Reactor Cooling Dinic求解 无源无汇有上下界的最大流