http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1314

题目大意:无源汇上下界网络流,问每个管子走多少流量才能满足所有管子的下界,如果没有方案输出“NO”。

————————————————————————

上下界网络流无源汇板子题。

显然参考了:https://www.cnblogs.com/kane0526/archive/2013/04/05/3001108.html

我们很直观的想到:我们把上界-下界,下界=0,那么不就可以跑正常流了?

显然不对,这不满足流量守恒定理。

于是我们考虑在它不平衡的时候人为的补充/流走流量。

当流入>流出,我们从st到该点建容量为流入-流出的边。

当流入<流出,我们从该点到ed建容量为流出-流入的边。

统计我们流入>流出时所有加的边的容量和,如果容量和不等于最大流,显然它不能保证所有边的下边界,就是no。

否则输出所有原边的反向边此时的容量即可。

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=;
const int M=;
const int INF=;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
struct node{
int nxt;
int to;
int w;
}edge[M];
int head[*N],low[M],out[N],in[N],cnt=-;
inline void add(int u,int v,int w){
cnt++;
edge[cnt].to=v;
edge[cnt].w=w;
edge[cnt].nxt=head[u];
head[u]=cnt;
return;
}
int lev[N],cur[N];
bool bfs(int m){//强制1为源点,m为汇点
int dui[m],r=;
for(int i=;i<=m;i++){
lev[i]=-;
cur[i]=head[i];
}
dui[]=,lev[]=;
int u,v;
for(int l=;l<=r;l++){
u=dui[l];
for(int e=head[u];e!=-;e=edge[e].nxt){
v=edge[e].to;
if(edge[e].w>&&lev[v]==-){
lev[v]=lev[u]+;
r++;
dui[r]=v;
if(v==m)return ;
}
}
}
return ;
}
int dinic(int u,int flow,int m){
if(u==m)return flow;
int res=,delta;
for(int &e=cur[u];e!=-;e=edge[e].nxt){
int v=edge[e].to;
if(edge[e].w>&&lev[u]<lev[v]){
delta=dinic(v,min(edge[e].w,flow-res),m);
if(delta>){
edge[e].w-=delta;
edge[e^].w+=delta;
res+=delta;
if(res==flow)break;
}
}
}
if(res!=flow)lev[u]=-;
return res;
}
inline void init(){
memset(head,-,sizeof(head));
memset(in,,sizeof(in));
memset(out,,sizeof(out));
cnt=-;
return;
}
int main(){
int t=read(),num=;
while(t--){
init();num++;
if(num>)puts("");
int n=read(),m=read();
for(int i=;i<=m;i++){
int u=read()+,v=read()+;
low[i]=read();
int up=read();
add(u,v,up-low[i]);
add(v,u,);
out[u]+=low[i];
in[v]+=low[i];
}
int st=,ed=n+,ans=,full=;
for(int i=;i<=n+;i++){
if(out[i]<in[i]){
add(st,i,in[i]-out[i]);
add(i,st,);
full+=in[i]-out[i];
}else{
add(i,ed,out[i]-in[i]);
add(ed,i,);
}
}
while(bfs(ed)==)ans+=dinic(st,INF,ed);
if(ans!=full)puts("NO");
else{
puts("YES");
for(int i=;i<m;i++){
printf("%d\n",edge[i*+].w+low[i+]);
}
}
}
return ;
}

最新文章

  1. 理解AUC
  2. MD5 、 加密工具
  3. Bootstrap使用初涉
  4. 怎样设置一个DIV在所有层的最上层,最上层DIV
  5. Laravle Introduction
  6. Shopilex - 开源免费网店系统
  7. Python入门(转)
  8. Jetty安装学习并展示
  9. ASP.NET 5 Overview
  10. 二叉树最大路径和-Binary Tree Maximum Path Sum
  11. Python2.7和3.7区别
  12. 『宝藏 状态压缩DP NOIP2017』
  13. AI - 机器学习常见算法简介(Common Algorithms)
  14. 使用soap遇到的缓存问题
  15. LeetCode:146_LRU cache | LRU缓存设计 | Hard
  16. RC1015 cannot open include file &#39;atlres.h&#39;
  17. Shell: nohup守护进程化
  18. json_encode 中文 null
  19. C#动态加载/卸载Assembly的解决方案
  20. Window下Neo4j安装教程

热门文章

  1. angular ng-bind-html $sce.trustAsHtml
  2. oradebug 的学习 一
  3. 使用union
  4. Android Preference 设置偏好全攻略
  5. 【springmvc+mybatis项目实战】杰信商贸-5.生产厂家DAO+SERVICE+CONTROLLER+JSP+配置文件
  6. PNG和PVR之间互相转换的脚本
  7. HashMap 阅读
  8. win32绘制自定义类窗口导致绘制11个窗口的解决办法
  9. Multi-task Correlation Particle Filter for Robust Object Tracking--论文随笔
  10. Python3 Tkinter-Place