SGU 176 Flow construction(有上下限的最小流)
题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=176
题意:给出一个有向图,边有边权。对于边有要求,要求有些边的流量恰好等于容量,其他边的流量要不大于其容量。在该要求下求最小流。1号点为源点,n号点为汇点。
思路:有上下限最小流。两种方法:
(1)构建的新图D和上面的D是一样的。也是先求S到T的最大流,此时记录<t,s>边的流量A,然后删掉边<t,s>,接着求t到s的最大流B,则答案为A-B。此时A-B有可能为0,原因是这个图本来最小流为0,由于有环的存在这个图可以自给自足,此时增加S到s的边<S,s,B-A>,再跑S到t(此时是原来图的汇点t)的最大流。这样,每条边的流量加上下限就是每条边的实际流量。
(2)二分t到s的上限。x=in[i]-out[i],x>=0,连边<S,i,x>,sum+=x,否则<i,T,-x>。求S到T的最大流,大于等于sum则可行。
#include <iostream> #include <string.h> #include <stdio.h> #define min(x,y) ((x)<(y)?(x):(y)) using namespace std;struct node {int x,y,b,c; };struct Node {int v,cap,flow,next;Node(){}Node(int _v,int _cap,int _flow,int _next){v=_v;cap=_cap;flow=_flow;next=_next;} };const int INF=1000000000; Node edges[120005]; node info[10005]; int n,m,s,t,S,T,head[1005],e; int num[1005],h[1005],curedge[1005],pre[1005];void Add(int u,int v,int cap) {edges[e]=Node(v,cap,0,head[u]);head[u]=e++;edges[e]=Node(u,0,0,head[v]);head[v]=e++; }int Maxflow(int s,int t,int n) {int ans=0,i,k,x,d,u;memset(num,0,sizeof(num));memset(h,0,sizeof(h));for(i=0;i<=n;i++) curedge[i]=head[i];num[n]=n;u=s;while(h[u]<n){if(u==t){d=INF+1;for(i=s;i!=t;i=edges[curedge[i]].v) if(d>edges[curedge[i]].cap)k=i,d=edges[curedge[i]].cap;for(i=s;i!=t;i=edges[curedge[i]].v){x=curedge[i];edges[x].cap-=d;edges[x].flow+=d;edges[x^1].cap+=d;edges[x^1].flow-=d;}ans+=d;u=k;}for(i=curedge[u];i!=-1;i=edges[i].next) if(edges[i].cap>0&&h[u]==h[edges[i].v]+1)break;if(i!=-1){curedge[u]=i;pre[edges[i].v]=u;u=edges[i].v;}else{if(--num[h[u]]==0) break;curedge[u]=head[u];for(x=n,i=head[u];i!=-1;i=edges[i].next) if(edges[i].cap>0&&h[edges[i].v]<x)x=h[edges[i].v];h[u]=x+1;num[h[u]]++;if(u!=s) u=pre[u];}}return ans; }int in[105],out[105];int main() {memset(head,-1,sizeof(head));e=0;int ans1,ans2,ans,i,sum=0;scanf("%d%d",&n,&m);if(n==0){puts("Impossible");return 0;}s=1;t=n;S=n+1;T=n+2;for(i=1;i<=m;i++){scanf("%d%d%d%d",&info[i].x,&info[i].y,&info[i].b,&info[i].c);if(info[i].c){sum+=info[i].b;in[info[i].y]+=info[i].b;out[info[i].x]+=info[i].b;Add(info[i].x,info[i].y,0);}else Add(info[i].x,info[i].y,info[i].b);}for(i=1;i<=n;i++){Add(S,i,in[i]);Add(i,T,out[i]);}Add(t,s,INF);if(Maxflow(S,T,n+2)!=sum){puts("Impossible");return 0;}ans1=edges[head[t]^1].cap;edges[head[t]].cap=0;edges[head[t]^1].cap=0;ans2=Maxflow(t,s,n+2);ans=ans1-ans2;if(ans<0){edges[head[t]].cap=0;edges[head[t]^1].cap=0;edges[e]=Node(s,-ans,0,head[S]);head[S]=e++;Maxflow(S,t,n+2);ans=0;}printf("%d\n",ans);for(i=1;i<=m;i++) printf(i==1?"%d":" %d",edges[i+i-1].cap+info[i].b*info[i].c);puts("");return 0; }
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> #include <cmath> #include <vector> #include <queue> #include <set> #include <stack> #include <string> #include <map>#define max(x,y) ((x)>(y)?(x):(y)) #define min(x,y) ((x)<(y)?(x):(y)) #define abs(x) ((x)>=0?(x):-(x)) #define i64 long long #define u32 unsigned int #define u64 unsigned long long #define clr(x,y) memset(x,y,sizeof(x)) #define CLR(x) x.clear() #define ph(x) push(x) #define pb(x) push_back(x) #define Len(x) x.length() #define SZ(x) x.size() #define PI acos(-1.0) #define sqr(x) ((x)*(x)) #define MP(x,y) make_pair(x,y) #define EPS 1e-9#define FOR0(i,x) for(i=0;i<x;i++) #define FOR1(i,x) for(i=1;i<=x;i++) #define FOR(i,a,b) for(i=a;i<=b;i++) #define FORL0(i,a) for(i=a;i>=0;i--) #define FORL1(i,a) for(i=a;i>=1;i--) #define FORL(i,a,b)for(i=a;i>=b;i--) using namespace std;void RD(int &x){scanf("%d",&x);} void RD(u32 &x){scanf("%u",&x);} void RD(double &x){scanf("%lf",&x);} void RD(int &x,int &y){scanf("%d%d",&x,&y);} void RD(u32 &x,u32 &y){scanf("%u%u",&x,&y);} void RD(double &x,double &y){scanf("%lf%lf",&x,&y);} void RD(int &x,int &y,int &z){scanf("%d%d%d",&x,&y,&z);} void RD(int &x,int &y,int &z,int &t){scanf("%d%d%d%d",&x,&y,&z,&t);} void RD(u32 &x,u32 &y,u32 &z){scanf("%u%u%u",&x,&y,&z);} void RD(double &x,double &y,double &z){scanf("%lf%lf%lf",&x,&y,&z);} void RD(char &x){x=getchar();} void RD(char *s){scanf("%s",s);} void RD(string &s){cin>>s;}void PR(int x) {printf("%d\n",x);} void PR(int x,int y) {printf("%d %d\n",x,y);} void PR(i64 x) {printf("%lld\n",x);} void PR(u32 x) {printf("%u\n",x);} void PR(double x) {printf("%.5lf\n",x);} void PR(char x) {printf("%c\n",x);} void PR(char *x) {printf("%s\n",x);} void PR(string x) {cout<<x<<endl;}struct Node {int u,v,cap,flow,next; };const int INF=1000000000; Node edges[120005]; int n,m,s,t,head[1005],e; int num[1005],h[1005],curedge[1005],pre[1005];void add(int u,int v,double cap) {edges[e].u=u;edges[e].v=v;edges[e].cap=cap;edges[e].flow=0.0;edges[e].next=head[u];head[u]=e++; }void Add(int u,int v,double cap) {add(u,v,cap);add(v,u,0.0); }int Maxflow(int s,int t,int n) {int ans=0,i,k,x,d,u;memset(num,0,sizeof(num));memset(h,0,sizeof(h));for(i=0;i<=n;i++) curedge[i]=head[i];num[n]=n;u=s;while(h[u]<n){if(u==t){d=INF+1;for(i=s;i!=t;i=edges[curedge[i]].v) if(d>edges[curedge[i]].cap)k=i,d=edges[curedge[i]].cap;for(i=s;i!=t;i=edges[curedge[i]].v){x=curedge[i];edges[x].cap-=d;edges[x].flow+=d;edges[x^1].cap+=d;edges[x^1].flow-=d;}ans+=d;u=k;}for(i=curedge[u];i!=-1;i=edges[i].next) if(edges[i].cap>0&&h[u]==h[edges[i].v]+1)break;if(i!=-1){curedge[u]=i;pre[edges[i].v]=u;u=edges[i].v;}else{if(--num[h[u]]==0) break;curedge[u]=head[u];for(x=n,i=head[u];i!=-1;i=edges[i].next) if(edges[i].cap>0&&h[edges[i].v]<x)x=h[edges[i].v];h[u]=x+1;num[h[u]]++;if(u!=s) u=pre[u];}}return ans; }struct Info {int u,v,b,c;void read(){RD(u,v,b,c);if(c==0) c=b,b=0;else c=b;} };Info a[10005]; int in[105],out[105];int OK(int mid) {clr(head,-1); e=0;clr(in,0),clr(out,0);int i,sum=0,x;a[m+1].u=n; a[m+1].v=1;a[m+1].b=0; a[m+1].c=mid;FOR1(i,m+1){in[a[i].v]+=a[i].b;out[a[i].u]+=a[i].b;Add(a[i].u,a[i].v,a[i].c-a[i].b);}int S=0,T=n+1;FOR1(i,n){x=in[i]-out[i];if(x>=0) Add(S,i,x),sum+=x;else Add(i,T,-x);}return Maxflow(S,T,T+1)>=sum; }int main() {RD(n,m);int i;FOR1(i,m) a[i].read();int low=0,high=INF,mid;while(low<=high){mid=(low+high)>>1;if(OK(mid)) high=mid-1;else low=mid+1;}int ans;if(high>=0&&OK(high)) ans=high;else if(OK(low)) ans=low;else ans=-1;if(ans==-1){puts("Impossible");return 0;}PR(ans);FOR1(i,m){if(i!=1) putchar(' ');printf("%d",edges[i+i-1].cap+a[i].b);}puts("");return 0; }
SGU 176 Flow construction(有上下限的最小流)相关推荐
- SGU-176 Flow construction 有上下界的最小流
这里参看了大牛的解题思路,学习了很多.原来上下界流的求法是这么的灵活,尤其我是用的临界表存储的边,删除更新很不方便. http://www.shuizilong.com/house/archives/ ...
- 【有源汇点上下界最小流】[SGU176]Flow construction
题目大意 给出N个点,M条有向边 如果有向边的标号是1的话,就表示该边的上界下界都为容量 如果有向边的标号为0的哈,表示该边的下界为0,上界为容量 现在问,从1到N的最小流是多少,并输出每条边的流量 ...
- 有上下界网络流 ---- P4843 清理雪道(DAG图上最小路径重复边覆盖)【模板】有源汇上下界最小流
题目链接 题目大意: 解题思路: 首先我们发现对于每条边至少要覆盖一次,最多覆盖无数次 那么就有点像上下界网络流了[1,INF][1,INF][1,INF]的限制关系 跑一边最小流就可以了!! #in ...
- HDU 3157 Crazy Circuits(有源汇上下界最小流)
HDU 3157 Crazy Circuits 题目链接 题意:一个电路板,上面有N个接线柱(标号1~N),还有两个电源接线柱 + -.给出一些线路,每一个线路有一个下限值求一个能够让全部部件正常工作 ...
- BZOJ 2502: 清理雪道 [最小流]
2502: 清理雪道 题意:任意点出发任意次每条边至少经过一次最小花费. 下界1,裸最小流.... #include <iostream> #include <cstdio> ...
- LOJ - #117. 有源汇有上下界最小流(有源汇有上下界的最小流)
题目链接:点击查看 题目大意:给出一个 n 个点和 m 条边的有向图,每条边都有一个流量限制 [ lower , upper ],给定源点 s 和汇点 t ,求出源点到汇点的最小流 题目分析:参考我的 ...
- POJ 3801/HDU 3157 Crazy Circuits | 有下界的最小流
题目: POJ最近总是炸 所以还是用HDU吧http://acm.hdu.edu.cn/showproblem.php?pid=3157 题解: 题很长,但其实就是给个有源汇带下界网络流(+是源,-是 ...
- 图论:有源汇有上下界最小流
这次就是最小流了 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const ll I ...
- 有汇源上下界最大流和最小流
有汇源上下界最大流 有源汇上下界最大流最小流理解 题目 理解 #include<bits/stdc++.h> using namespace std; const int N=610,M= ...
- [BZOJ2502]清理雪道解题报告|带下界的最小流
滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道),弧的方向代表斜坡下降的方向. 你的团队负责每周定时清理雪道.你们拥有一架直升飞机,每次飞 ...
最新文章
- 区块链与边缘计算(1)基本概念
- mybatis配置问题
- nodejs TCP server和TCP client如何进行数据交互
- .net 微服务实践
- hashset java_Java HashSet clear()方法与示例
- python学习之random
- Activity生命周期Android,横屏切换不重新创建Activity, Activity的四种launchMode
- 互联网企业架构初期选择--初期技术选型
- turbo c是什么?
- 5款创业在线学习的工具
- 国企计算机岗位职称申请,在国企工作如何评定职称
- 计算机毕设 SpringBoot 校园志愿者管理系统 志愿者管理系统 志愿者信息管理系统Java Vue MySQL数据库 远程调试 代码讲解
- 限制性立方样条(Restricted Cubic Spline)
- 雅可比(Jacobi)及高斯-塞德尔(Gauss_Seidel)迭代法求解线性方程组的matlab现实
- Win8.1 安装NLTK及nltk数据
- android逆向分析腾讯微视研究无限循环视频嵌套滑动不中断的实现方式
- 3dvary灯光材质为什么不亮_3dmax灯光教程灯光打出来太假?不真实?杂点?曝光?原因都在这儿呢...
- 最新高频Java面试题目分享,分布式ID(数据库多主模式
- Typora自动上传图床配置
- 经典的三角形软件测试用例
热门文章
- Flink CDC + Hudi + Hive + Presto 构建实时数据湖最佳实践
- Android TV开发总结【适配】
- c语言spoc期末考试及答案,MOOC-SPOC测试题(部分答案)(至数组一章)-C语言-宣城校区2016年.docx...
- java xss 参数_JAVA 重写HttpServletRequest的获取参数防止xss攻击
- 奥鹏2019计算机应用基础1,奥鹏东师2019年秋季(计算机应用基础)离线考核(仅供参考).docx...
- java基本操作-2
- visual studio怎么编译python_我的计算机上的Python使用哪个版本的Visual Studio进行编译?...
- 会议室预约微信小程序推荐_又是BYPASS!微信小程序预约 YEEZY BOOST 350 V2 只要3S就能搞定!...
- 32位crc校验码程序_基于FPGA的CRC校验码生成器设计
- mysql实现主从复制的方式_mysql实现主从复制、读写分离的配置方法(二)