无源汇上下界网络流

题目描述

这是一道模板题。

n n n 个点,m m m 条边,每条边 e e e 有一个流量下界 lower(e) \text{lower}(e) lower(e) 和流量上界 upper(e) \text{upper}(e) upper(e),求一种可行方案使得在所有点满足流量平衡条件的前提下,所有边满足流量限制。

输入格式

第一行两个正整数 n n n、m m m。

之后的 m m m 行,每行四个整数 s s s、t t t、lower \text{lower} lower、upper \text{upper} upper。

输出格式

如果无解,输出一行 NO

否则第一行输出 YES,之后 m m m 行每行一个整数,表示每条边的流量。

样例

样例输入 1

4 6
1 2 1 2
2 3 1 2
3 4 1 2
4 1 1 2
1 3 1 2
4 2 1 2

样例输出 1

NO

样例输入 2

4 6
1 2 1 3
2 3 1 3
3 4 1 3
4 1 1 3
1 3 1 3
4 2 1 3

样例输出 2

YES
1
2
3
2
1
1

数据范围与提示

1≤n≤200,1≤m≤10200 1 \leq n \leq 200, 1 \leq m \leq 10200 1n200,1m10200

 

思路分析:

代码示例 :

const int maxn = 1e5+5;
const int inf = 0x3f3f3f3f;

int n, m;
struct node
{
    int to, next;
    int flow;
}e[maxn];
int head[maxn];
int cnt;
int s, t, sum;

void addedge(int u, int v, int w){
    e[cnt].to = v, e[cnt].flow = w, e[cnt].next = head[u], head[u] = cnt++;
    e[cnt].to = u, e[cnt].flow = 0, e[cnt].next = head[v], head[v] = cnt++;
}
int dep[500], que[500];

bool bfs(int s, int t){
    memset(dep, 0, sizeof(dep));
    dep[s] = 1; que[0] = s;
    int head1 = 0, tail = 1;
   
    while(head1 < tail) {
        int v = que[head1++];
        for(int i = head[v]; i != -1; i = e[i].next){
            int to = e[i].to;
            if (e[i].flow && !dep[to]) {
                dep[to] = dep[v]+1;
                que[tail++] = to;
            }
        }
    } 
    return dep[t];
}

int dfs(int u, int f1){
    if (u == t || f1 == 0) return f1;
    int f = 0;
    for(int i = head[u]; i != -1; i = e[i].next){
        int to = e[i].to;
        if (e[i].flow && dep[to] == dep[u]+1){
            int x = dfs(to, min(e[i].flow, f1));
            e[i].flow -= x, e[i^1].flow += x;
            f1 -= x, f += x;
            if (f1 == 0) return f;
        }
    }
    if (!f) dep[u] = -2;
    return f;
}
int id[15000], ans[15000];

void maxflow() {
    int res = 0;
    
    while(bfs(s, t)){
        res += dfs(s, inf);
    }
    if (res == sum) {
        printf("YES\n");
        for(int i = 1; i <= m; i++){
            printf("%d\n", e[id[i]].flow+ans[i]);
        }       
    } 
    else printf("NO\n");
}

int main() {
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    cin >> n >> m;
    int u, v, x, y;
    s = 0, t = n+1;
    memset(head, -1, sizeof(head)); 
    
    for(int i = 1; i <= m; i++){
        scanf("%d%d%d%d", &u, &v, &x, &y);
        addedge(u, v, y-x); 
        id[i] = cnt-1;
        addedge(s, v, x);
        addedge(u, t, x);      
        sum += x;   
        ans[i] = x; 
    }
    maxflow();
    return 0;
}

 

posted @ 2018-11-10 16:10  楼主好菜啊  阅读(224)  评论(0编辑  收藏  举报