Reactor Cooling
sgu194:http://acm.sgu.ru/problem.php?contest=0&problem=194
题意:题目大意:给n个点,及m根pipe,每根pipe用来流躺液体的,单向的,每时每刻每根pipe流进来的物质要等于流出去的物质,要使得m条pipe组成一个循环体,里面流躺物质。并且满足每根pipe一定的流量限制,范围为[Li,Ri].即要满足每时刻流进来的不能超过Ri(最大流问题),同时最小不能低于Li。
题解:题解:。对于每根管子有一个上界容量up和一个下界容量low,我们让这根管子的容量下界变为0,上界为up-low。可是这样做了的话流量就不守恒了,为了再次满足流量守恒,即每个节点"入流=出流”,我们增设一个超级源点st和一个超级终点sd。我们开设一个数组du[]来记录每个节点的流量情况。du[i]=in[i](i节点所有入流下界之和)-out[i](i节点所有出流下界之和)。当du[i]大于0的时候,st到i连一条流量为du[i]的边。当du[i]小于0的时候,i到sd连一条流量为-du[i]的边。最后对(st,sd)求一次最大流即可,如果从源点流出的边都满流了,则就有可行解,否则无解。
1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #include<cstring> 5 #include<algorithm> 6 #define min(a,b)(a<b?a:b) 7 #define INF 1000000 8 using namespace std; 9 const int MAX=100010; 10 struct Node { 11 int c; 12 int f; 13 }; 14 int sx,ex;//sx和ex分别代表源点和汇点 15 int pre[MAX]; 16 Node map[209][203]; 17 int n,m; 18 int du[MAX]; 19 int dx[MAX],ll[MAX],rr[MAX];//记录每条边的流量下界,起点,终点 20 bool BFS() { //BFS搜索层次网络 21 memset(pre,0,sizeof(pre)); 22 queue< int > Q; 23 Q.push(sx); 24 pre[sx]=1; 25 while(!Q.empty()) { 26 int d=Q.front(); 27 Q.pop(); 28 for(int i=0; i<=n+1; i++) { 29 if(!pre[i]&&map[d][i].c-map[d][i].f) { 30 pre[i]=pre[d]+1; 31 Q.push(i); 32 } 33 } 34 } 35 return pre[ex]!=0; 36 } 37 int dinic(int pos,int flow) { //pos是顶点号,flow是当前顶点所能得到的流量,一次dinic只能求出一次增加的流量, 38 int f=flow; 39 if(pos==ex) 40 return flow; 41 for(int i=0; i<=1+n; i++) { 42 if(map[pos][i].c-map[pos][i].f&&pre[pos]+1==pre[i]) { 43 int a=map[pos][i].c-map[pos][i].f; 44 int t=dinic(i,min(a,flow)); 45 map[pos][i].f+=t; 46 map[i][pos].f-=t; 47 flow-=t; 48 if(flow<=0)break; 49 //我最开始就是这里没弄明白,我不明白为什么要此顶点得到的流量减去改变量; 50 //答案就在下面的 return f-flow; 51 } 52 } 53 if(f-flow<=0)pre[pos]=-1; 54 return f-flow;//其实这里返回给他前一层的就是这个t;因为t在层函数里面都有,所以所过避免重复就写成这样; 55 } 56 void slove(){ 57 int sum=0; 58 while(BFS()) { 59 sum+=dinic(sx,INF); 60 } 61 //return sum; 62 } 63 int main() { 64 int u,v,t1,t2; 65 while(cin>>n>>m) { 66 memset(du,0,sizeof(du)); 67 sx=0; 68 ex=n+1; 69 memset(map,0,sizeof(map)) ; 70 for(int i=1;i<=m; i++) { 71 cin>>u>>v>>t1>>t2; 72 map[u][v].c+=t2-t1; 73 du[u]-=t1; 74 du[v]+=t1; 75 dx[i]=t1; 76 ll[i]=u; 77 rr[i]=v; 78 } 79 for(int i=1;i<=n;i++){ 80 if(du[i]>0)map[0][i].c+=du[i]; 81 if(du[i]<0)map[i][n+1].c+=(-du[i]); 82 } 83 slove(); 84 bool flag=false; 85 for(int i=1;i<=n;i++){ 86 if(du[i]>0){ 87 if(map[0][i].f!=map[0][i].c){ 88 flag=true; 89 break; 90 } 91 92 } 93 } 94 if(flag)printf("NO\n"); 95 else{ 96 printf("YES\n"); 97 for(int i=1;i<=m;i++){ 98 printf("%d\n",map[ll[i]][rr[i]].f+dx[i]); 99 } 100 } 101 } 102 return 0; 103 }