博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【无源汇上下界最大流】SGU 194 Reactor Cooling
阅读量:5174 次
发布时间:2019-06-13

本文共 3078 字,大约阅读时间需要 10 分钟。

题目链接:

  

题目大意:

  n个点n<20000!!!不是200!!!RE了无数次,m条边(管子)(m范围好像没说,我开了10^6),每个点流入的和流出的液体要相等,每条边(管子)有上下界流量,问是否有解,有解YES无解NO,有解还要输出每条边的流量。

  题目输入样例略坑,我以为要多组数据输入输出TEST #1 什么的。后来仔细看了Input发现只有一组吧应该,保险起见还是写了多组,但是不用读入TEST是肯定的。

题目思路:

  【无源汇上下界最大流】

  直接建图套最大流模版即可。

  最近刚好在搞上下界问题,等到都做完了写个总结吧。

  建图模型:(学习自 )

  以前写最大流默认下界为0,而这里的下界却不为0,所以我们要进行再构造让每条边的下界为0,这样做是为了方便处理。

  对于每条边(管子)有一个上界容量c和一个下界容量b,我们让这条边(管子)的容量下界变为0,上界为b-c。

  可是这样做的话流量就不守恒了,为了再次满足流量守恒,增设一个超级源点S和一个超级终点T。

  我们开设一个数组in[]来记录每个节点的流量情况。

  in[i]=Σi入下界i出下界(i节点所有入流下界之和-i节点所有出流下界之和)。

  当in[i]大于0的时候,S到i连一条流量为in[i]的边。

  当in[i]小于0的时候,i到T连一条流量为-in[i]的边。

  最后对(S,T)求一次最大流即可,当所有附加边全部满流时(S的出边都满流时),有可行解。

  

1 //  2 //by coolxxx  3 //  4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include
14 #include
15 #define min(a,b) ((a)<(b)?(a):(b)) 16 #define max(a,b) ((a)>(b)?(a):(b)) 17 #define abs(a) ((a)>0?(a):(-(a))) 18 #define lowbit(a) (a&(-a)) 19 #define sqr(a) (a)*(a) 20 #define swap(a,b) (a)^=(b),(b)^=(a),(a)^=(b) 21 #define eps 1e-8 22 #define MAX 0x7f7f7f7f 23 #define PI 3.1415926535897 24 #define N 20004 25 #define M 1000004 26 using namespace std; 27 int n,m,cas,lll,ans; 28 int S,T,nn; 29 int last[N],in[N],d[N],vd[N],low[N]; 30 char s[N]; 31 bool inq[N]; 32 struct xxx 33 { 34 int next,to,f; 35 }e[M]; 36 void add(int x,int y,int f) 37 { 38 e[++lll].next=last[x]; 39 last[x]=lll; 40 e[lll].to=y; 41 e[lll].f=f; 42 } 43 void link(int x,int y,int f) 44 { 45 add(x,y,f); 46 add(y,x,0); 47 } 48 void build() 49 { 50 int i,f,x,y,b,c; 51 lll=1;ans=0; 52 memset(low,0,sizeof(low)); 53 memset(in,0,sizeof(in)); 54 memset(last,0,sizeof(last)); 55 memset(e,0,sizeof(e)); 56 memset(d,0,sizeof(d)); 57 memset(vd,0,sizeof(vd)); 58 scanf("%d",&m); 59 for(i=1;i<=m;i++) 60 { 61 scanf("%d%d%d%d",&x,&y,&b,&c); 62 in[x]-=b;in[y]+=b; 63 link(x,y,c-b); 64 low[i]=b; 65 } 66 S=n+1; 67 T=n+2; 68 nn=n+2; 69 for(i=1;i<=n;i++) 70 { 71 if(in[i]>0)link(S,i,in[i]); 72 if(in[i]<0)link(i,T,-in[i]); 73 } 74 } 75 int sap(int u,int f) 76 { 77 int i,tt,asp=0,mix=nn-1; 78 if(u==T)return f; 79 for(i=last[u];i;i=e[i].next) 80 { 81 if(e[i].f>0) 82 { 83 if(d[u]==d[e[i].to]+1) 84 { 85 tt=sap(e[i].to,min(f-asp,e[i].f)); 86 asp+=tt; 87 e[i].f-=tt; 88 e[i^1].f+=tt; 89 if(asp==f || d[S]==nn) 90 return asp; 91 } 92 mix=min(mix,d[e[i].to]); 93 } 94 } 95 if(asp!=0)return asp; 96 if(!--vd[d[u]])d[S]=nn; 97 else vd[d[u]=mix+1]++; 98 return asp; 99 }100 int main()101 {102 #ifndef ONLINE_JUDGE103 // freopen("1.txt","r",stdin);104 // freopen("2.txt","w",stdout);105 #endif106 int i,j,f;107 // while(~scanf("%s",s))108 while(~scanf("%d",&n) && n)109 {110 build();111 vd[0]=nn;112 while(d[S]
0)120 {121 f=0;122 break;123 }124 }125 if(!f)126 puts("NO");127 else128 {129 puts("YES");130 for(i=1;i<=m;i++)131 printf("%d\n",low[i]+e[i+i+1].f);132 }133 }134 return 0;135 }136 137 138 /*139 //140 141 //142 */
View Code

 

转载于:https://www.cnblogs.com/Coolxxx/p/5321790.html

你可能感兴趣的文章
注意java的对象引用
查看>>
C++ 面向对象 类成员函数this指针
查看>>
NSPredicate的使用,超级强大
查看>>
自动分割mp3等音频视频文件的脚本
查看>>
判断字符串是否为空的注意事项
查看>>
布兰诗歌
查看>>
(转)Tomcat 8 安装和配置、优化
查看>>
(转)Linxu磁盘体系知识介绍及磁盘介绍
查看>>
跨域问题整理
查看>>
[Linux]文件浏览
查看>>
获取国内随机IP的函数
查看>>
Spring Mvc模式下Jquery Ajax 与后台交互操作
查看>>
(转)matlab练习程序(HOG方向梯度直方图)
查看>>
tableView
查看>>
Happy Great BG-卡精度
查看>>
TCP/IP 邮件的原理
查看>>
原型设计工具
查看>>
windows下的C++ socket服务器(4)
查看>>
css3 2d转换3d转换以及动画的知识点汇总
查看>>
计算机改名导致数据库链接的诡异问题
查看>>