zoukankan      html  css  js  c++  java
  • hdu 4940 无源汇有上下界最大流

    /*
    <img src="http://img.blog.csdn.net/20140823174212937?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMTQ4MzMwNg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
    题意:给出一个有向强连通图,每条边有两个值分别是破坏该边的代价和把该边建成无向边的代价(建立无向边的前提是删除该边)问是否存在一个集合S,和一个集合的补集T,破坏所有S集合到T集合的边代价和是X,然后修复T到S的边为无向边代价和是Y,满足Y<X;满足输出unhappy,否则输出happy;
    分析:无源汇有上下界可行流判定, 原来每条边转化成  下界为D  上界为 D+B   ,判断是否存在可行流即可。</span>
     如果存在可行流  那么说明对于任意的 S 集合流出的肯定等于 流入的, 流出的计算的 X 肯定小于等于这个流量(X是下界之和), 计算出来的Y (上界之和)肯定大于等于 这个流量  肯定满足X<=Y。
    */
    #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
    ",++k);
                else
                    printf("Case #%d: unhappy
    ",++k);
            }
    
    return 0;
    }
    

  • 相关阅读:
    C语言 realloc为什么要有返回值,realloc返回值具体解释/(解决随意长度字符串输入问题)。
    opencv中的vs框架中的Blob Tracking Tests的中文注释。
    Java实现 蓝桥杯VIP 算法提高 棋盘多项式
    Java实现 蓝桥杯VIP 算法提高 棋盘多项式
    Java实现 蓝桥杯VIP 算法提高 棋盘多项式
    Java实现 蓝桥杯VIP 算法提高 棋盘多项式
    Java实现 蓝桥杯VIP 算法提高 分苹果
    Java实现 蓝桥杯VIP 算法提高 分苹果
    Java实现 蓝桥杯VIP 算法提高 分苹果
    Java实现 蓝桥杯VIP 算法提高 分苹果
  • 原文地址:https://www.cnblogs.com/thefirstfeeling/p/4410633.html
Copyright © 2011-2022 走看看