sgu 194上下界网络流

又搞了个模板,这个模板应该ok,足以应付各种网络流了

题意:给n个点m 条边,其中每条边的流量有两个限制不能大于r不能小于l,求是否有可行解,如有输出每条边的流量

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 1000000;
const int oo = 0x3777777;
struct arc{
    int to,cap,flow,next;
    arc(int x = 0,int y=0,int z = 0,int u =0){
        to = x;cap = y;
        flow = z;next = u;
    }
};
arc e[maxn];
int head[maxn],d[maxn],tot,id[maxn],work[maxn];
int S,T,q[maxn],hd,tail,n,m;
void add(int u,int v,int cap,int flow,int ID){
    id[tot] = ID;
    e[tot] = arc(v,cap,flow,head[u]);
    head[u] = tot++;
    id[tot] = 0;
    e[tot] = arc(u,0,-flow,head[v]);
    head[v] = tot++;
}

bool bfs(){
    for(int i=1;i<=T;i++)
    d[i] = 0;
    d[S] = 1;
    hd = tail = 0;
    q[tail++] = S;
    while(hd != tail){
        int u = q[hd++];
        if(hd == maxn)hd  =0;
        for(int i=head[u];i!=-1;i=e[i].next){
             if(e[i].cap > e[i].flow && !d[e[i].to]){
                d[e[i].to] = d[u] + 1;
                q[tail++] = e[i].to;
                if(tail == maxn)tail = 0;
                if(T == e[i].to)return true;
             }
        }
    }
    return false;
}
int dfs(int u,int low){
    int tmp = 0,f;
    if(u==T||!low)return low;
    for(int &i=work[u];i!=-1;i=e[i].next){
            if(d[e[i].to] == d[u] + 1 && (f=dfs(e[i].to,min(low,e[i].cap - e[i].flow)))){
               // tmp += f;
                e[i].flow += f;
                e[i^1].flow -= f;
              //  low -= f;
              //  if(!low)break;
              return f;
            }
    }
    return 0;
}
void init(){
    memset(head,-1,sizeof(head));
    tot = 0;
}
int du[maxn],dn[maxn],ans[maxn];
int main(){
    int u,v,down,up;
    while(~scanf("%d%d",&n,&m)){
        init();
        for(int i=1;i<=m;i++){
            scanf("%d%d%d%d",&u,&v,&down,&up);
            add(u,v,up-down,0,i);
            du[u] -= down;
            du[v] += down;
            dn[i] = down;
        }
        S = 0;T=n+1;
        int Edge = tot;
        for(int i=1;i<=n;i++){
            if(du[i] > 0) add(S,i,du[i],0,0);
            if(du[i] < 0) add(i,T,-du[i],0,0);
        }
        while(bfs())
        {
            for(int i=0; i<n+2; i++)
            work[i]=head[i];
            while(dfs(S,oo));
        }
        int flag = 0;
        for(int i=head[S];i!=-1;i=e[i].next){
            if(e[i].flow != e[i].cap){
                flag = 1;break;
            }
        }
        if(flag)puts("NO");
        else {
            puts("YES");
            for(int i = 0;i<Edge;i++) ans[id[i]] = e[i].flow;
            for(int i=1;i<=m;i++)
                printf("%d\n",ans[i]+dn[i]);
        }

    }
}
时间: 2024-08-02 21:57:07

sgu 194上下界网络流的相关文章

sgu 194 上下界网络流可行流判定+输出可行流

1 #include <cstdio> 2 #include <cstring> 3 #define min(a,b) ((a)<(b)?(a):(b)) 4 #define oo 0x3f3f3f3f 5 #define N 210 6 #define M 100010 7 8 struct Dinic { 9 int n, src, dst; 10 int head[N], dest[M], flow[M], eid[M], next[M], etot; 11 int c

sgu 176 上下界网络流最小可行流带输出方案

算法步骤: 1. 先将原图像最大可行流那样变换,唯一不同的是不加dst->src那条边来将它变成无源无汇的网络流图.直接跑一边超级源到超级汇的最大流. 2. 加上刚才没有加上的那条边p 3. 再跑一遍超级源汇之间的最大流,p的流量就是我们要求的最小可行流流量(等于其反向边的"容量") 收获: 1. 最大可行流和最小可行流,当我们把其残量网络求出来后,其流量就是dst->src的残量. 每条边在此时的流量 = 流量下界 + 转换后对应边的流量 1 #include <c

@总结 - 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.

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

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

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

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

上下界网络流总结

1.无源汇上下界可行流 对于(u,v)有向边,上界为a,下界为b 构图方法为: (1) ss 到 v 容量为 b (2) u 到 tt 容量为 b (3) u 到 v 容量为 a-b 求ss-tt最大流,当且仅当 maxflow=sigma(i,t)=sigma(s,i) 时 存在可行流 2.有源汇上下界最小流 如果发现原图无源汇,要先转化为有源汇 其他点如1方法,建图,另加 t-s 容量为 inf 求一遍 ss-tt最大流,此时s-t的流量为 t-s这条边的反向边的流量,记为 x 在残量网络中

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的下界总