LOJ模板题 无源汇有上下界可行流
来源:互联网 发布:电信4g网络覆盖范围 编辑:程序博客网 时间:2024/06/06 07:18
https://loj.ac/problem/115
没有loj我都不知道有这种操作。
如何求得一个无源汇的图是否可行呢,是一个网络流可以解决的问题。
首先,我们知道每条边的起点u,终点v,下界low,上界up。最初始的图理应是由各条边的下界流量组成的。
然后我们看一看每个点是否能做到流入量和流出量平衡。本来就平衡的话就不用管这个点了。如果不平衡,我们分情况讨论
如果对于点p,流入量比流出量多x,那么我们建立一条超级源点ss到p流量上界为x的边。
反之,建立一条p到超级汇点tt的流量上界为x的边。
此时跑一遍网络流,如果与超级源点相连的边都满流了,也就说明超级汇点也满流了,整个图是可行的。否则是不可行的。
若还想知道每条边在可行方案中的流量是多少,我们可以用这条边的下界流量加上跑完网络流后这条边的反边的流量即可。
比如loj上的样例
4 61 2 1 32 3 1 33 4 1 34 1 1 31 3 1 34 2 1 3
一开始建立的图:
我们可以从每条边的下界先分析出某些点流入和流出不相等,按照上面的方法,我们建立超级源点和超级汇点。得到
整个图已经建立起来了,上面的数字都是当前边最大的可行流量(原来的边的流量就是up-low),当前流量是为0的。跑一遍网络流可得
那么可以看到和超级源点所连的边都是满流的,所以有可行方案。每条边的流量就是每条边的下界加上跑完网络流后当前边的流量。
代码如下:
#include<iostream>#include<cstring>#include<cstdio>#include<queue>const int maxn = 205;const int maxm = 10500;using namespace std;inline int read(){int x=0,t=1,c;while(!isdigit(c=getchar()))if(c=='-')t=-1;while(isdigit(c))x=x*10+c-'0',c=getchar();return x*t;}int head[maxn],cur[maxn],nx[maxm<<1],to[maxm<<1],flow[maxm<<1],ppp=2;struct Dinic{int d[maxn];int s,t;long long ans;void AddEdge(int u,int v,int c){to[ppp]=v;flow[ppp]=c;nx[ppp]=head[u];head[u]=ppp++;swap(u,v);to[ppp]=v;flow[ppp]=0;nx[ppp]=head[u];head[u]=ppp++;}bool BFS(){memset(d,-1,sizeof d);d[t]=1;queue<int> Q;Q.push(t);while(!Q.empty()){int x=Q.front();Q.pop();for(int i=head[x];i;i=nx[i]){if(flow[i^1]&&d[to[i]]==-1){d[to[i]]=d[x]+1;Q.push(to[i]);}}}return d[s]!=-1;}int DFS(int x,int maxflow){if(x==t||!maxflow){ans+=maxflow;return maxflow;}int ret=0,f;for(int &i=cur[x];i;i=nx[i]){if(d[to[i]]==d[x]-1&&(f=DFS(to[i],min(maxflow,flow[i])))){ret+=f;flow[i]-=f;flow[i^1]+=f;maxflow-=f;if(!maxflow)break;}}return ret;}long long solve(int source,int tank){s=source;t=tank;ans=0;while(BFS()){memcpy(cur,head,sizeof(cur));DFS(s,2147483647);}return ans;}}dinic;int ru[maxn], low[maxm], sum;int main(){int n=read(),m=read();for(int i = 0; i < m; i++){int u=read(),v=read();low[i] = read();int up = read();dinic.AddEdge(u,v,up - low[i]);ru[u] -= low[i];ru[v] += low[i];}for(int i = 1; i <= n; i++) {if(ru[i] > 0) {dinic.AddEdge(0, i, ru[i]);sum += ru[i];} else if(ru[i] < 0) {dinic.AddEdge(i, n + 1, -ru[i]);}}int tmp = dinic.solve(0,n + 1);if(tmp == sum) {cout << "YES" << '\n';for(int i = 0; i < m; i++) {printf("%d\n", low[i] + flow[2 + i * 2 + 1]);}} else {cout << "NO" << '\n';}return 0;}
阅读全文
0 0
- LOJ模板题 无源汇有上下界可行流
- LOJ #115. 无源汇有上下界可行流
- loj #115. 无源汇有上下界可行流
- 无源汇有上下界可行流存在定理
- 【无源汇有上下界可行流】ZOJ-2314 Reactor Cooling
- [ZOJ2314]Reactor Cooling(无源汇有上下界的可行流)
- 无源汇有上下界可行流(网络流进阶)
- 无源汇有上下界可行流详解(loj115)
- zoj 2314 reactor cooling(无源汇有上下界可行流)
- 无源汇上下界可行流模版
- zoj 2314 Reactor Cooling (无源汇有上下界的可行流)
- ZOJ 1324 Reactor Cooling——无源汇有上下界的可行流
- zoj 2314(无源汇上下界可行流)
- ZOJ 2314 Reactor Cooling 无源汇上下界可行流
- SGU 194 无源汇的上下界可行流
- ★ zoj 2314 无源汇上下界可行流
- 无源无汇带上下界的可行流
- 无源汇上下界可行流(多校7)
- 搭建简单的mongodb服务器
- 【RabbitMQ】——Spring AMQP
- Android实现收款成功金额的语音播报功能(Nice tone)
- pyaudio 编译相关问题
- iOS 蓝牙低功耗使用
- LOJ模板题 无源汇有上下界可行流
- [LeetCode] 150. Evaluate Reverse Polish Notation
- 多个线程多把锁
- Flask学习笔记--11
- 终止Java线程
- 调用dialog.show时报异常
- arcgis javascript 鹰眼图
- iOS lable设置富文本后在最后一行没有显示省略号的问题解决
- 资讯精选 | 流量攻击态势严峻_微软7月漏洞汇总和修复建议