SGU 194 Reactor Cooling

没有源点和汇点、流量有上下界的网络最大流问题。

今天看了一下午的有上下界的网络最大流问题,在似懂非懂、非常朦胧的状态下过了这个题...激动了半天。

求解的方法:http://www.cnblogs.com/zufezzt/p/4681035.html

AC代码:

#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;

const int maxn=1000+10;
const int INF=0x7FFFFFFF;

struct Edge
{
    int from,to,cap,flow,up,low;
};
vector<Edge>edges;
vector<int>G[maxn];
bool vis[maxn];
int d[maxn];
int cur[maxn];
int Out[maxn],In[maxn];
int s,t;

//求出层次网络
bool BFS()
{
    memset(vis,0,sizeof(vis));
    queue<int>Q;
    Q.push(s);
    d[s]=0;
    vis[s]=1;
    while(!Q.empty())
    {
        int x=Q.front();
        Q.pop();
        for(int i=0; i<G[x].size(); i++)
        {
            Edge& e=edges[G[x][i]];
            if(!vis[e.to]&&e.cap>e.flow)
            {
                vis[e.to]=1;
                d[e.to]=d[x]+1;
                Q.push(e.to);
            }
        }
    }
    return vis[t];
}

//加边
void AddEdge(int from,int to,int low,int up)
{
    int m;
    Edge r;
    r.from=from;
    r.to=to;
    r.cap=up-low;
    r.flow=0;
    r.low=low;
    r.up=up;
    edges.push_back(r);
    Edge d;
    d.from=to;
    d.to=from;
    d.cap=0;
    d.flow=0;
    //r.low=low;r.up=up;
    edges.push_back(d);
    m=edges.size();
    G[from].push_back(m-2);
    G[to].push_back(m-1);
}

//每个阶段来一次DFS增广
int DFS(int x,int a)
{
    if(x==t||a==0) return a;
    int flow=0,f;
    for(int i=cur[x]; i<G[x].size(); i++)
    {
        Edge& e=edges[G[x][i]];
        if(d[x]+1==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0)
        {
            e.flow+=f;
            edges[G[x][i]^1].flow-=f;
            flow+=f;
            a-=f;
            if(a==0) break;
        }
    }
    return flow;
}

//多个阶段,多次建立层次网络。
int Maxflow(int ss,int tt)
{
    int flow=0;
    while(BFS())
    {
        memset(cur,0,sizeof(cur));
        flow+=DFS(ss,INF);
    }
    return flow;
}

int main()
{
    int N,M,i,j;
    while(~scanf("%d%d",&N,&M))
    {

        edges.clear();
        for(int i=0; i<maxn; i++) G[i].clear();
        memset(In,0,sizeof(In));
        memset(Out,0,sizeof(Out));
        s=0;
        t=N+1;

        for(i=1; i<=M; i++)
        {
            int u,v,low,up;
            scanf("%d%d%d%d",&u,&v,&low,&up);
            AddEdge(u,v,low,up);
            In[v]=In[v]+low;
            Out[u]=Out[u]+low;
        }

        for(i=1; i<=N; i++)
        {
            AddEdge(i,t,0,Out[i]);
            AddEdge(s,i,0,In[i]);
        }

        Maxflow(s,t);

        int flag=1;
        for(i=0; i<edges.size(); i++)
            if(edges[i].from==s)
                if(edges[i].flow<edges[i].cap)
                {
                    flag=0;
                    break;
                }
        if(!flag) printf("NO\n");
        else
        {
            printf("YES\n");
            for(i=0; i<2*M; i++)
                if(i%2==0)
                    printf("%d\n",edges[i].flow+edges[i].low);
        }
    }
    return 0;
}
时间: 2024-10-28 16:17:42

SGU 194 Reactor Cooling的相关文章

SGU 194 Reactor Cooling 带容量上下限制的网络流

建立虚拟的源点和汇点,因为忽略掉了容量下界之后会导致流量不平衡,所以对于每个u,v,u多出来的流量流到汇点,v不够的流量从源点补流 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <ma

SGU 194 Reactor Cooling (有容量和下界的可行流)

题意:给定上一个有容量和下界的网络,让你求出一组可行解. 析:先建立一个超级源点 s 和汇点 t ,然后在输入时记录到每个结点的下界的和,建边的时候就建立c - b的最后再建立 s 和 t , 在建立时,如果 i 结点的输入的大于输出的,那么就是从 s 建立一条边,否则 i 与 t 建立,然后跑一次最大流,就OK了,注意求出的流量是没有下界,再加上下界的就好了. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000")

SGU 194 Reactor Cooling ——网络流

[题目分析] 无源汇上下界可行流. 上下界网络流的问题可以参考这里.↓ http://www.cnblogs.com/kane0526/archive/2013/04/05/3001108.html [代码] #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> //#include <map> #include <set> #include

sgu 194 Reactor Cooling(有容量上下界的无源无汇可行流)

[题目链接] http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=20757 [题意] 求有容量上下界的无源无汇可行流. [思路] 无源无汇可行流要求所有的顶点都满足流量平衡. 基本思路是转化成最大流来做. 对于边(u,v,b,c),连边(u,v,c-b).为了保持流量平衡,我们还需要连边         1.(S,u,inB[u]-outB[u])  inB>outB 2.(u,T,outB[u]-inB[u])  outB>

SGU 194. Reactor Cooling(无源汇有上下界的网络流)

时间限制:0.5s 空间限制:6M 题意: 显然就是求一个无源汇有上下界的网络流的可行流的问题 Solution: 没什么好说的,直接判定可行流,输出就好了 code /* 无汇源有上下界的网络流 */ #include <iostream> #include <cstring> #define ms(a,b) memset(a,b,sizeof a) using namespace std; const int MAXN = 209; struct node { int u, v

SGU 194 Reactor Cooling Dinic求解 无源无汇有上下界的最大流

题目链接 题意:有向图中有n(1 <= n <= 200)个点,无自环或者环的大小至少为3.给定每条边的最小流量和最大流量,问每条边的可行流量为多少? 思路:一般求解的网络流并不考虑下界问题,即流量可以为0,在有下界时,我们只需将上界变成r-l,这时还需要满足流量守恒,增加源点s和汇点t,当点u的流入大于流出时,将点u与s连边,容量即为多出的流量.同理当u流出大于流入时,多出来的流出的流量连到汇点t;直接跑最大流: 注:这时判断是否存在可行解时,是看连到源点的所有边是否满流,全为满流说明内部流

【SGU 194】 Reactor Cooling

194. Reactor Cooling time limit per test: 0.5 sec. memory limit per test: 65536 KB input: standard output: standard The terrorist group leaded by a well known international terrorist Ben Bladen is buliding a nuclear reactor to produce plutonium for t

acdream 1211 Reactor Cooling 【边界网络流量 + 输出流量】

称号:acdream 1211 Reactor Cooling 分类:无汇的有上下界网络流. 题意: 给n个点.及m根pipe,每根pipe用来流躺液体的.单向的.每时每刻每根pipe流进来的物质要等于流出去的物质,要使得m条pipe组成一个循环体.里面流躺物质. 而且满足每根pipe一定的流量限制,范围为[Li,Ri].即要满足每时刻流进来的不能超过Ri(最大流问题).同一时候最小不能低于Li. 比如: 46(4个点,6个pipe) 12 1 3 (1->2上界为3,下界为1) 23 1 3

ZOJ2314 Reactor Cooling

Reactor Cooling Time Limit: 5 Seconds      Memory Limit: 32768 KB      Special Judge The terrorist group leaded by a well known international terrorist Ben Bladen is buliding a nuclear reactor to produce plutonium for the nuclear bomb they are planni