• 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]);
            }
        }
    }
  • 相关阅读:
    应用程序池的配置 狼
    SQL跨数据库复制表数据 狼
    <script language= "javascript " for= "window " event= "onload "> 狼
    禁止虚拟目录继承根目录下web.config中的有些配置 web.config的继承禁止方法 狼
    linux 在程序里修改系统时间
    xlinux下载地址
    安装tslib1.4出现的问题汇总
    linux之看门狗 (转)
    VC中显示GIF图片
    mdev 自动挂载U盘成功
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8334108.html
Copyright © 2020-2023  润新知