SGU 194 Reactor Cooling 有上下界的网络流 网络流拆点

前端之家收集整理的这篇文章主要介绍了SGU 194 Reactor Cooling 有上下界的网络流 网络流拆点前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

无源汇有上下界限制网络流

拆点可解

设超级源点 ss 和超级汇点 tt

deg[i] = i 点的流入容量和 - i 点的流出容量和

若 deg[i] > 0 建立 ss -> i 边权为 deg[i] 的边 强行流出 deg[i] 的流量

若 deg[i] < 0 建立 i -> tt 边权为 -deg[i] 的边 强行流入 -deg[i] 的流量

代码(AC,15ms

#include<iostream>
#include<queue>
#include<cstdlib>
#include<vector>
#include<cstring>
#include<cstdio>
using namespace std;
const int INF = 0x7ffffff;
const int MAXN = 205;
const int MAXM = MAXN * MAXN;
int n,m,s,t,cnt;
bool vis[MAXN];
int head[MAXN],deg[MAXM],dl[MAXM];
int d[MAXN],cur[MAXN],que[MAXN];
struct edge_{
    int from,to,cap,flow,next;
}edge[MAXM];

void init(){
    memset(head,-1,sizeof(head));
    memset(edge,sizeof(edge));
    memset(deg,sizeof(deg));
    cnt = 0;
}

void add(int from,int to,int cap){
    edge[cnt].from = from,edge[cnt].to = to;
    edge[cnt].cap = cap,edge[cnt].next = head[from];
    edge[cnt].flow = 0;
    head[from] = cnt++;
    edge[cnt].from = to,edge[cnt].to = from;
    edge[cnt].cap = 0,edge[cnt].next = head[to];
    edge[cnt].flow = 0;
    head[to] = cnt++;
}

bool bfs(){
    memset(vis,false,sizeof(vis));
    memset(d,sizeof(d));
    d[s] = 0,vis[s] = 1,que[0] = s;
    int tail = 0,front = 1;
    while(tail < front){
        int x = que[tail++];
        for(int now = head[x]; ~now; now = edge[now].next){
            edge_ &e = edge[now];
            if(!vis[e.to] && e.cap > e.flow){
                vis[e.to] = 1;
                d[e.to] = d[x] + 1;
                que[front++] = e.to;
            }
        }
    }
    return vis[t];
}

int dfs(int x,int a){
    if(x == t || a == 0)
        return a;
    int flow = 0,f;
    for(int &now = cur[x]; ~now; now = edge[now].next){
        edge_ &e = edge[now];
        if(d[x] + 1 == d[e.to] && (f = dfs(e.to,min(a,e.cap - e.flow))) > 0){
            e.flow +=f;
            edge[now ^ 1].flow -= f;
            flow += f;
            a -= f;
            if(a == 0)
                break;
        }
    }
    return flow;
}

int maxFlow(int _s,int _t,int _n,int _m){
    s = _s,t = _t;
    n = _n,m = _m;
    int flow = 0;
    while(bfs()){
        for(int i = 1; i <= n; i++)
            cur[i] = head[i];
        flow += dfs(s,INF);
    }
    return flow;
}

int main(){
    int n,l,r,ss,tt;
    while(~scanf("%d%d",&n,&m)){
        init();
        ss = n + 1,tt = n + 2;
        for(int i = 1; i <= m; ++i){
            scanf("%d%d%d%d",&s,&t,&l,&r);
            deg[s] -= l,deg[t] += l,dl[i] = l;
            add(s,r - l);
        }
        int sum = 0;
        for(int i = 1; i <= n; ++i){
            if(deg[i] > 0){
                add(ss,i,deg[i]);
                sum += deg[i];
            }
            else
                add(i,tt,-deg[i]);
        }
        if(maxFlow(ss,n + 2,m) == sum){
            printf("YES\n");
            for(int i = 0; i < m; ++i)
                printf("%d\n",edge[i * 2].flow + dl[i + 1]);
        }
        else{
            printf("NO\n");
        }
    }
    return 0;
}

猜你在找的React相关文章