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

3 4 1 3

4 1 1 3

1 3 1 3

4 2 1 3

可行流:

再如:所有pipe的上界为2下界为1的话,就不能得到一种可行流。

题解:

上界用ci表示,下界用bi表示。

下界是必须流满的,那么对于每一条边,去掉下界后,其自由流为ci– bi。

主要思想:每一个点流进来的流=流出去的流

对于每一个点i,令

Mi= sum(i点所有流进来的下界流)– sum(i点所有流出去的下界流)

如果Mi大于0,代表此点必须还要流出去Mi的自由流,那么我们从源点连一条Mi的边到该点。

如果Mi小于0,代表此点必须还要流进来Mi的自由流,那么我们从该点连一条Mi的边到汇点。

如果求S->T的最大流,看是否满流(S的相邻边都流满)。

满流则有解,否则无解。

AC代码:

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
#define Del(a,b) memset(a,b,sizeof(a))
using namespace std;
const int inf = 0x3f3f3f3f;
const int N = 250;
struct Node
{
    int from,to,cap,flow;
};
vector<int> v[N];
vector<Node> e;
int vis[N];  //构建层次图
int cur[N];
void add_Node(int from,int to,int cap)
{
    e.push_back((Node){from,to,cap,0});
    e.push_back((Node){to,from,0,0});
    int tmp=e.size();
    v[from].push_back(tmp-2);
    v[to].push_back(tmp-1);
}
bool bfs(int s,int t)
{
    Del(vis,-1);
    queue<int> q;
    q.push(s);
    vis[s] = 0;
    while(!q.empty())
    {
        int x=q.front();
        q.pop();
        for(int i=0;i<v[x].size();i++)
        {
            Node tmp = e[v[x][i]];
            if(vis[tmp.to]<0 && tmp.cap>tmp.flow)  //第二个条件保证
            {
                vis[tmp.to]=vis[x]+1;
                q.push(tmp.to);
            }
        }
    }
    if(vis[t]>0)
        return true;
    return false;
}
int dfs(int o,int f,int t)
{
    if(o==t || f==0)  //优化
        return f;
    int a = 0,ans=0;
    for(int &i=cur[o];i<v[o].size();i++) //注意前面 ’&‘,很重要的优化
    {
        Node &tmp = e[v[o][i]];
        if(vis[tmp.to]==(vis[o]+1) && (a = dfs(tmp.to,min(f,tmp.cap-tmp.flow),t))>0)
        {
            tmp.flow+=a;
            e[v[o][i]^1].flow-=a; //存图方式
            ans+=a;
            f-=a;
            if(f==0)  //注意优化
                break;
        }
    }
    return ans;  //优化
}
int dinci(int s,int t)
{
    int ans=0;
    while(bfs(s,t))
    {
        Del(cur,0);
        int tm=dfs(s,inf,t);
        ans+=tm;
    }
    return ans;
}
void MP_clear(int n)
{
    for(int i=0;i<=n;i++)
        v[i].clear();
    e.clear();
}
int come[N],to[N];
int flow[N][N];
struct Node1
{
    int x,y;
}num[N*N];
int main()
{
    int n,m;
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        Del(come,0);
        Del(to,0);
        Del(flow,0);
        int s=0,t = n+1;
        for(int i=0;i<m;i++)
        {
            int x,y,mi,ma;
            scanf("%d%d%d%d",&x,&y,&mi,&ma);
            num[i] = (Node1){x,y};
            flow[x][y] += mi;
            add_Node(x,y,ma-mi);
            come[x]+= mi;
            to[y] += mi;
        }
        int count=0;
        for(int i=1;i<=n;i++)
        {
            int tmp = come[i]-to[i];
            if(tmp<0)
            {
                count+=tmp;
                add_Node(s,i,-tmp);
            }
            if(tmp>0)
                add_Node(i,t,tmp);
        }
        count = -count;
        int ans = dinci(s,t);
        if(ans != count)
            puts("NO");
        else
        {
            puts("YES");
            for(int i=1;i<=n;i++)
            {
                for(int j=0;j<v[i].size();j++)
                {
                    int f = v[i][j];
                    flow[e[f].from][e[f].to]+=abs(e[f].flow);
                    //printf("xx %d %d %d \n",e[f].from,e[f].to,e[f].flow);
                }
            }
            for(int i=0;i<m;i++)
            {
                printf("%d\n",flow[num[i].x][num[i].y]);
            }
        }
        if(T)
            puts("");
        MP_clear(t);
    }
    return 0;
}
时间: 2024-10-27 06:29:37

acdream 1211 Reactor Cooling 【上下界网络流 + 输出流量】的相关文章

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 --- 上下界可行流

题目给出了每条边的上下界, 此类题目的建边方法是: 1.添加源点汇点, 2.对每条边 添加边 c(u,v) = up(u,v) - low(u,v) 3.对每个点 c(s,v) = out(v) c(v,t) = in(v)   (权值为正) 求s到t的最大流,若最大流等于所有边下界的和,则存在可行流, 每条边的流量为 flow(u,v) +low(u,v) #include <iostream> #include <cstring> #include <string>

[ACdream 1211 Reactor Cooling]无源无汇有上下界的可行流

题意:无源无汇有上下界的可行流 模型 思路:首先将所有边的容量设为上界减去下界,然后对一个点i,设i的所有入边的下界和为to[i],所有出边的下界和为from[i],令它们的差为dif[i]=to[i]-from[i],根据流量平衡原理,让出边和入边的下界相抵消,如果dif[i]>0,说明入边把出边的下界抵消了,还剩下dif[i]的流量必须要流过来(否则不满足入边的下界条件),这时从源点向i连一条容量为dif[i]的边来表示即可,如果dif[i]<0,同理应该从i向汇点连一条容量为-dif[i

ZOJ 2314 Reactor Cooling 无源汇有上下界网络流

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1314 题意:给出N个点,M条边的有向图,每条边的有上下界规定,问是否存在一个可行流满足条件,如果满足输出YES并输出每条边的流量. 如果不满足输出NO. 根据周源的<一种简易的方法求解流量有上下界的网络中网络流问题> 无源汇上下界网络流的做法是: 设边u->v的下界是B(u,v),上界是C(u,v). 设M(i)为对于i结点的流入i的下界总和-流出i的下界总

【有上下界网络流】【ZOJ】2314 Reactor Cooling

[算法]有上下界网络流-无源汇(循环流) [题解] 无源汇网络流相当于重建图后跑最大流. 循环流要求每个点(或边)的流入量和流出量相等. http://www.cnblogs.com/liu-runda/p/6262832.html http://hzwer.com/3356.html 入度>出度时(in[x]>0)时,需要流出去,所以从源向点引一条边,引诱它流出去. 入度<出度时(in[x]<0)时,需要流进来,所以从点向汇引一条边,引诱它流进来. 为何这样正确?源和汇的作用只是

ZOJ Problem Set - 3229 Shoot the Bullet 【有上下界网络流+流量输出】

题目:ZOJ Problem Set - 3229 Shoot the Bullet 分类:有源有汇有上下界网络流 题意:有 n 天和 m 个girls,然后每天给一部分girls拍照,每个girls 有拍照的下限,即最少要拍这么多张,然后每天有k个女孩拍照,摄影师最多可以拍num张,然后 k 个女该每天拍照数量值有上下限,然后问你有没有满足这样条件的给女孩拍照的最大方案,然后按照输入输出每天给女孩拍照的张数. 做这道题目推荐先做:这儿 分析:首先它让你判断能不能满足条件. 按照题目给出的条件很

@总结 - 8@ 上下界网络流等一类网络流问题

目录 @0 - 参考资料@ @1 - 问题引入@ @2 - 上下界可行流@ @3 - 上下界最大流/最小流@ @4 - 上下界费用流@ @5 - 带负环的最小费用流@ @6 - 例题与参考代码实现@ @7 - 一些类似的杂题@ @0 - 参考资料@ menci 的博客 liu_runda 的博客 @1 - 问题引入@ 我们知道,通常情况下,一个合法的流应该具有如下几个性质: (1)(除源点汇点以外)流量守恒:\(\sum f(i, u) = \sum f(u, j)\). (2)斜对称性:\(f

有上下界的网络流2-有源汇带上下界网络流ZOJ3229

ZOJ3229题目大意:一个屌丝给m个女神拍照,计划拍照n天,每一天屌丝可以和C个女神拍照,每天拍照数不能超过D张,而且给每个女神i拍照有数量限制[Li,Ri],对于每个女神n天的拍照总和不能少于Gi,如果有解求屌丝最多能拍多少张照,并求每天给对应女神拍多少张照:否则输出-1. 解题思路:        1.增设一源点st,汇点sd,st到第i天连一条上界为Di下界为0的边,每个女神到汇点连一条下界为Gi上界为正无穷的边,对于每一天,当天到第i个女孩连一条[Li,Ri]的边.        2.

Acdream 1171 Matrix sum 上下界费用流

题目链接:点击打开链接 Matrix sum Time Limit: 8000/4000MS (Java/Others)Memory Limit: 128000/64000KB (Java/Others) SubmitStatisticNext Problem Problem Description sweet和zero在玩矩阵游戏,sweet画了一个N * M的矩阵,矩阵的每个格子有一个整数.zero给出N个数Ki,和M个数Kj,zero要求sweet选出一些数,满足从第 i 行至少选出了Ki