zoukankan      html  css  js  c++  java
  • ZOJ2314 Reactor Cooling

    题目大意是这样的,给出n个点和m条边,每个边有一个流量的上下界,问是否存在一个循环的流量。这就是典型的无汇源点的上下界网络流,也就是循环流。做法是这样的,首先每条边我们都添加最少的流量,由于要满足流量守恒的条件,即每个点的流出量等于流入量,那么我们尝试进行修改,添加新的流量。我们记录一下每个点流出量与流入量的差,新建虚拟汇点源点,如果一个点流入量大于流出量,那么我们把他连向汇点,反之连向源点(容量都取绝对值),然后原来的m条边流量全部变为上下界的差。这样有源点有汇点的网络流就建出来了,跑一下最大流,如果最大流等于我们源点连出来的所有边的容量之和,那么就是有解的,反之就无解。因为我们新建的网络流源点与汇点的流量之和一定相同(原图上每个边的贡献为0,两两抵消),如果最大流满流意味着我们在每条边流量为下限的时候找到了一条新的流量使得原图的流量守恒,而我们取得是流量的下限,如果此时找不到流量守恒的流量,那么肯定就无解了。 —— by VANE

    #include<cstdio>
    #include<queue>
    #include<cstring>
    using namespace std;
    const int N=300;
    const int M=N*400;
    int ss,tt,pre[M],other[M],last[N],l=1,cap[M],low[M];
    int n,m,d[N],flow[M],dis[N];
    void add(int a,int b,int c)
    {
        ++l;pre[l]=last[a];last[a]=l;other[l]=b;cap[l]=c;flow[l]=0;
        swap(a,b);++l;pre[l]=last[a];last[a]=l;other[l]=b;cap[l]=0;flow[l]=0;
    }
    bool bfs()
    {
        memset(dis,0,sizeof dis);
        queue<int> q;
        q.push(ss);
        dis[ss]=1;
        while(!q.empty())
        {
            int u=q.front();q.pop();
            for(int p=last[u];p;p=pre[p])
            {
                int v=other[p];
                if(!cap[p]||dis[v]) continue;
                dis[v]=dis[u]+1;
                q.push(v);
            }
        }
        if(dis[tt]) return 1;
        return 0;
    }
    int dfs(int x,int f)
    {
        if(x==tt) return f;
        if(f==0) return 0;
        int res=f;
        for(int p=last[x];p;p=pre[p])
        {
            int v=other[p];
            if(dis[v]!=dis[x]+1||!cap[p]) continue;
            if(!res) break;
            int tmp=dfs(v,min(cap[p],res));
            res-=tmp;
            cap[p]-=tmp;
            flow[p]+=tmp;
            cap[p^1]+=tmp;
            flow[p^1]-=tmp;
            if(tmp==0) dis[v]=-1;
        }
        return f-res;
    }
    int dinic()
    {
        int res=0;
        while(bfs()) res+=dfs(ss,1e9);
        return res;
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            l=1;
            memset(d,0,sizeof d);
            memset(last,0,sizeof last);
            scanf("%d%d",&n,&m);
            ss=n+1;tt=n+2;
            for(int i=1;i<=m;++i)
            {
                int a,b,c;
                scanf("%d%d%d%d",&a,&b,&low[i],&c);
                add(a,b,c-low[i]);
                d[a]+=low[i];
                d[b]-=low[i];
            }
            int tot=0;
            for(int i=1;i<=n;++i)
            {
                if(d[i]<0) add(ss,i,-d[i]);
                else add(i,tt,d[i]),tot+=d[i];
            }
            if(dinic()!=tot) puts("NO");
            else
            {
                puts("YES");
                for(int i=1;i<=m;++i)
                printf("%d
    ",flow[i<<1]+low[i]);
            }
        }
    }
  • 相关阅读:
    企业视频会议EasyRTC视频云服务是如何满足不同企业多场景直播的?
    TSINGSEE青犀视频H265网页播放器EasyPlayerPro-Win如何通过配置文件实现自动播放等功能?
    TSINGSEE青犀视频自主研发H265播放器EasyPlayerPro-Win C++如何获取软件版本信息源码
    RTMP视频直播点播平台EasyDSS及企业视频通话会议系统EasyRTC内启动nginx 配置重定向功能介绍
    面向对象程序设计上机练习二(函数模板)
    2014暑假ACM训练总结
    codeforces 之 Little Pigs and Wolves
    SDUT 2766 小明传奇2
    0-1背包的总结
    POJ 2063 Investment (完全背包)
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8334108.html
Copyright © 2011-2022 走看看