首页 > 代码库 > hdu 4940 无源汇有上下界最大流
hdu 4940 无源汇有上下界最大流
题意:给出一个有向强连通图,每条边有两个值分别是破坏该边的代价和把该边建成无向边的代价(建立无向边的前提是删除该边)问是否存在一个集合S,和一个集合的补集T,破坏所有S集合到T集合的边代价和是X,然后修复T到S的边为无向边代价和是Y,满足Y<X;满足输出unhappy,否则输出happy;</span>
<span style="font-family: Arial, Helvetica, sans-serif;">分析:无源汇有上下界可行流判定, 原来每条边转化成 下界为D 上界为 D+B ,判断是否存在可行流即可。</span>
如果存在可行流 那么说明对于任意的 S 集合流出的肯定等于 流入的, 流出的计算的 X 肯定小于等于这个流量(X是下界之和), 计算出来的Y (上界之和)肯定大于等于 这个流量 肯定满足X<=Y。 <img src=http://www.mamicode.com/"http://img.blog.csdn.net/20140814105713964?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbXlwc3E=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />>#include<stdio.h> #include<string.h> #include<queue> using namespace std; #define N 300 #define inf 0x3fffffff struct node { int u,v,w,next; }bian[N*N*3]; int head[N],yong,dis[N],work[N]; void init(){ yong=0; memset(head,-1,sizeof(head)); } void addbian(int u,int v,int w) { bian[yong].u=u; bian[yong].v=v; bian[yong].w=w; bian[yong].next=head[u]; head[u]=yong++; } void add(int u,int v,int w) { addbian(u,v,w); addbian(v,u,0); } int min(int a,int b) { return a<b?a:b; } int bfs(int s,int t) { memset(dis,-1,sizeof(dis)); queue<int>q; q.push(s); dis[s]=0; while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=bian[i].next) { int v=bian[i].v; if(bian[i].w&&dis[v]==-1) { dis[v]=dis[u]+1; q.push(v); if(v==t) return 1; } } } return 0; } int dfs(int s,int limit,int t) { if(s==t)return limit; for(int &i=work[s];i!=-1;i=bian[i].next) { int v=bian[i].v; if(bian[i].w&&dis[v]==dis[s]+1) { int tt=dfs(v,min(limit,bian[i].w),t); if(tt) { bian[i].w-=tt; bian[i^1].w+=tt; return tt; } } } return 0; } int dinic(int s,int t) { int ans=0; while(bfs(s,t)) { memcpy(work,head,sizeof(head)); while(int tt=dfs(s,inf,t)) ans+=tt; } return ans; } int main(){ int sum,a,b,c,T,d,ans,i,k=0,n,m,t,S,w[N]; scanf("%d",&t); while(t--) { init(); scanf("%d%d",&n,&m); S=0;T=n+1; memset(w,0,sizeof(w)); for(i=1;i<=m;i++) { scanf("%d%d%d%d",&a,&b,&c,&d); add(a,b,d); w[b]+=c; w[a]-=c; } sum=0; for(i=1;i<=n;i++) { if(w[i]>0) { sum+=w[i]; add(S,i,w[i]); } if(w[i]<0) add(i,T,-w[i]); } ans=dinic(S,T); if(sum==ans) printf("Case #%d: happy\n",++k); else printf("Case #%d: unhappy\n",++k); } return 0; }hdu 4940 无源汇有上下界最大流
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。