HDU 4940 无源无汇上下界最大流

来源:互联网 发布:linux目录命令 编辑:程序博客网 时间:2024/06/05 05:53


题意具体解释


题目意思其实是对于每个点来说,从这个点流出的流量,能通过其他边流动回来,这就是无源无汇有上下界的最大流了。

对于每条有向边来说。  它的下界是  B,  上界是B+D。

参考 周源 《一种简易的方法求解流量有上下界的网络中网络流问题》  的构图方法




对于原图,更改容量,C'(u, v) = C(u, v) - B(u, v) , 同时  C(u,v) = 就是题目给出的B+D,  B(u,v) = 题目给出的 B

同时,增设源点S,汇点T

对于每个点,如果M( i ) > 0,则建边<S, i, M( i )>,如果M(i) < 0,则建边< i, T, -M( i )>

对新图求一次S-->T最大流,如果与S, T相连的边全部满流,则原图中存在一个可行流,保证每个点的流量守恒。


//tpl//ipqhjjybj_tpl.h//header.h#include <cstdio>#include <cstdlib>#include <map>#include <set>#include <algorithm>#include <cstring>#include <iostream>#include <vector>#include <string>#include <queue>#include <sstream>#include <math.h>#define mp(x,y) make_pair(x,y)#define pii pair<int,int>#define pLL pair<long long ,long long>#define pb(x) push_back(x)#define rep(i,j,k) for(int i = j; i < k;i++)#define MAX(x,a)  x=((x)<(a))?(a):(x);#define MIN(x,a)  x=((x)>(a))?(a):(x);using namespace std;const int N = 500;int n,m,tot;int s,t;int sum;struct node{int u,v,w,next;node(){}node(int _u,int _v,int _w,int _next){u=_u,v=_v,w=_w,next=_next;}}edge[N*N];int head[N],cur[N],dis[N];int pre[N],gap[N],aug[N];const int oo=0x3f3f3f;void addEdge(int u,int v,int w){edge[tot]=node(u,v,w,head[u]);head[u]=tot++;edge[tot]=node(v,u,0,head[v]);head[v]=tot++;}int SAP(int s,int e,int n){int max_flow=0,v,u=s;int id,mindis;aug[s]=oo;pre[s]=-1;memset(dis,0,sizeof(dis));memset(gap,0,sizeof(gap));gap[0]=n;for(int i=0;i <= n;i++)cur[i]=head[i];while(dis[s]<n){if(u==e){max_flow += aug[e];for(v=pre[e]; v!=-1; v=pre[v]){int ed=cur[v];edge[ed].w -= aug[e];edge[ed^1].w += aug[e];aug[v]-=aug[e];if(edge[ed].w==0) u=v;}}bool flag=false;for(id=cur[u]; id!=-1;id=edge[id].next){v=edge[id].v;if(edge[id].w > 0 && dis[u]==dis[v]+1){flag=true;pre[v]=u;cur[u]=id;aug[v]=min(aug[u],edge[id].w);u=v;break;}}if(flag==false){if(--gap[dis[u]] == 0) break; int mindis=n;for(id=head[u]; id!=-1; id=edge[id].next){v=edge[id].v;if(edge[id].w>0 && dis[v] < mindis){mindis = dis[v];cur[u]=id;}}dis[u] = mindis + 1;gap[dis[u]]++;if(u!=s)u=pre[u];}}return max_flow;}int in[N];int main(){int Cas,tt=0;scanf("%d",&Cas);while(Cas--){scanf("%d %d",&n,&m);tot=sum=s=0;memset(head,-1,sizeof(head));memset(in,0,sizeof(in));t = n+1;int sum_flow =0;rep(i,0,m){int u,v,b,d;scanf("%d %d %d %d",&u,&v,&b,&d);addEdge(u,v,d);in[v]+=b;in[u]-=b;}rep(i,1,n+1){if(in[i] > 0){sum_flow += in[i];addEdge(s,i,in[i]);}else{addEdge(i,t,-in[i]);}}int ans_flow = SAP(s,t,t+1);printf("Case #%d: ",++tt);if(ans_flow == sum_flow) puts("happy");else puts("unhappy");}return 0;}



0 0
原创粉丝点击