ZOJ 2314 (无源汇可行流)

#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <map>
#include <set>
using namespace std;
typedef long long LL;

#define V 210

#define E 100000
#define INF 10000000



int n, m;


//
//void init(){
//    nv = n+2;
//    ne = 0;
//    for (int i = 0; i < nv; i++){
//        adj[i] = -1, h[i] = 0, gap[i] = 0;
//    }
//}
//
//void add(int u, int v, int c){
//    to[ne] = v, cap[ne] = c, nxt[ne] = adj[u], adj[u] = ne++;
//    to[ne] = u, cap[ne] = 0, nxt[ne] = adj[v], adj[v] = ne++;
//}
//int dfs(int u, int flow){
//    if (u == t)return flow;
//    int f = flow, minh = nv, v;
//    for (int i = adj[u]; ~i; i = nxt[i]){
//        if (cap[i]){
//            v = to[i];
//            if (h[u] == h[v] + 1){
//                int aug = dfs(v, min(f, cap[i]));
//                f -= aug, cap[i] -= aug, cap[i^1] += aug;
//            }
//        }
//        if (--gap[h[u]] == 0)h[s] = nv;
//        else{
//            for (int i = adj[u]; ~i; i = nxt[i]){
//                if (cap[i]){
//                    minh = min(minh, h[to[i]]);
//                }
//                gap[h[u] = minh + 1]++;
//            }
//        }
//    }
//    return flow - f;
//}
//#define INF (-1u>>1)
//int max_flow(int s, int t){
//    int ret = 0;
//    gap[0] = nv, ::s = s, ::t = t;
//    while (h[s] < nv)ret += dfs(s, INF);
//    return ret;
//}

int nv, ne, to[E], cap[E], nxt[E], adj[V];
int h[V], gap[V], s, t;

void init()
{
    nv = n + 2;
    ne = 0;
    for (int i = 0; i < nv; i++)
        adj[i] = -1, h[i] = 0, gap[i] = 0;
}

//add函数只对应一条有向边
void add(const int &u, const int &v, const int &c)
{
    to[ne] = v, cap[ne] = c, nxt[ne] = adj[u], adj[u] = ne++;
    to[ne] = u, cap[ne] = 0, nxt[ne] = adj[v], adj[v] = ne++;
}

int dfs(const int &u, const int &flow)
{
    if (u == t) return flow;
    int f = flow, minh = nv, v;
    for (int i = adj[u]; ~i; i = nxt[i])
        if (cap[i])
        {
            v = to[i];
            if (h[u] == h[v] + 1)
            {
                int aug = dfs(v, min(f, cap[i]));
                f -= aug, cap[i] -= aug, cap[i ^ 1] += aug;
            }
            if (h[s] == nv || f == 0)   return flow - f;
        }
    if (--gap[h[u]] == 0)   h[s] = nv;
    else
    {
        for (int i = adj[u]; ~i; i = nxt[i])
            if (cap[i])
                minh = min(minh, h[to[i]]);
        gap[h[u] = minh + 1]++;
    }
    return flow - f;
}

int max_flow(const int &s, const int &t)
{
    int ret = 0;
    gap[0] = nv, ::s = s, ::t = t;
    while (h[s] < nv) ret += dfs(s, INF);
    return ret;
}


int in[V], out[V];
int l[E], r[E], idx[E];
int main(){
   // freopen("in.txt", "r", stdin);
    int ca;
    scanf ("%d", &ca);
    while (ca--){
        scanf ("%d%d", &n, &m);
        int x, y;


        fill(in, in + n + 2, 0);
        fill(out, out+n+2, 0);
        init();
        for (int i = 0; i < m; i++){
            scanf ("%d%d%d%d", &x, &y, l+i, r+i);
            idx[i] = ne;
            add(x, y, r[i] - l[i]);
            in[y] += l[i];
            out[x] += l[i];
        }
        int tot = 0;
        for (int i = 1; i <= n; i++){
            int t = in[i] - out[i];
            if (t > 0){
                add(0, i, t);
                tot += t;
            }else{
                add(i, n+1, -t);
            }
        }

       int ans=  max_flow(0, n+1);
       if (ans != tot){
            puts("NO");
       }
        else {
            puts("YES");
            for (int i = 0; i < m; i++){
                printf ("%d\n", cap[idx[i]^1] + l[i]);
            }
        }
        if (ca != 0)puts("");



    }

    return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值