[伪·ZOJ2314] 无源汇有上下界的最大流

来源:互联网 发布:js 把内容动态写入div 编辑:程序博客网 时间:2024/05/20 08:44

因为ZOJ测不了,就乱写了一个,主要是没数据

#include<iostream>#include<cstring>#include<cstdio>#define INF 0x7fffffffusing namespace std;const int N = 100005;int TT,S,T,d[N],b[N],h[N],q[N],ans,sum;int cnt=1,last[N];int n,m;struct Edge{    int to,v,next;}e[N*4];void insert( int u, int v, int w ){    e[++cnt].to = v; e[cnt].v = w; e[cnt].next = last[u]; last[u] = cnt;    e[++cnt].to = u; e[cnt].v = 0; e[cnt].next = last[v]; last[v] = cnt;}void init(){    ans = sum = 0; cnt = 1;    memset(d,0,sizeof(d));    memset(h,-1,sizeof(h));    memset(last,0,sizeof(last));}bool bfs(){    int head = 0, tail = 1;    memset(h,-1,sizeof(h));    q[0] = 0; h[0] = 0;    while( head != tail ){        int now = q[head++]; if( now == T ) return true;        for( int i = last[now]; i; i = e[i].next )            if( e[i].v && h[e[i].to] == -1 ){                h[e[i].to] = h[now] + 1;                q[tail++] = e[i].to;            }    }    return h[T] != -1;}int dfs( int x, int f ){    if( x == T ) return f;    int w,used = 0;    for( int i = last[x]; i; i = e[i].next )        if( e[i].v && h[e[i].to] == h[x] + 1 ){            w = dfs( e[i].to, min(f-used,e[i].v) );            e[i].v -= w; e[i^1].v += w; used += w;            if( used == f ) return used;        }    if( !used ) h[x] = -1;    return used;}void dinic(){    while(bfs()){        ans += dfs(S,INF);    }}int main(){    scanf("%d", &TT);    while( TT-- ){        init();        scanf("%d%d", &n, &m);        S = 0; T = n+1;        for( int i = 1,u,v,l,r; i <= m; i++ ){            scanf("%d%d%d%d", &u, &v, &l, &r); insert( u, v, r-l );            d[u] -= l; d[v] += l;        }        for( int i = 1; i <= n; i++ )            if( d[i] > 0 ) insert( S, i, d[i] ), sum += d[i];            else if( d[i] < 0 ) insert( i, T, -d[i] );        dinic();        if( ans == sum ) printf("YES %d\n",ans);        else printf("NO %d\n",ans);    }    return 0;}
阅读全文
0 0
原创粉丝点击