题目链接:https://loj.ac/problem/115

解法:

#include <bits/stdc++.h>
using namespace std;
const int mn=22222;
const int mm=1000000;
const int oo=0x3fffffff;
int node, st, sd, edge, Edge;
int reach[mm], flow[mm], Next[mm];
int head[mn], work[mn], dis[mn], que[mn];
int du[mm], ans[mm], id[mm], dn[mm];

inline void init(int _node, int _st, int _sd)
{
    node=_node, st=_st, sd=_sd;
    for(int i=0; i<node; i++)
        head[i]=-1;
    edge=0;
}

inline void addedge(int u, int v, int c1, int c2, int ID)
{
    id[edge]=ID, reach[edge]=v, flow[edge]=c1, Next[edge]=head[u],head[u]=edge++;
    id[edge]=0, reach[edge]=u, flow[edge]=c2, Next[edge]=head[v],head[v]=edge++;
}

bool bfs()
{
    int u, v, l=0, h=0;
    for(int i=0; i<node; i++) dis[i]=-1;
    que[l++]=st;
    dis[st]=0;
    while(l!=h)
    {
        u=que[h++];
        if(h==mn) h=0;
        for(int i=head[u]; i>=0; i=Next[i])
        {
            v=reach[i];
            if(flow[i]&&dis[v]<0)
            {
                dis[v]=dis[u]+1;
                que[l++]=v;
                if(l==mn) l=0;
                if(v==sd) return true;
            }
        }
    }
    return false;
}

int dfs(int u, int exp)
{
    if(u==sd) return exp;
    for(int &i=work[u]; i>=0; i=Next[i])
    {
        int v=reach[i], tp;
        if(flow[i]&&dis[v]==dis[u]+1&&(tp=dfs(v,min(flow[i],exp)))>0)
        {
            flow[i]-=tp;
            flow[i^1]+=tp;
            return tp;
        }
    }
    return 0;
}

void Dinic()
{
    while(bfs())
    {
        for(int i=0; i<node; i++) work[i]=head[i];
        while(dfs(st,oo));
    }
}

int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        init(n+2,0,n+1);
        for(int i=1; i<=m; i++)
        {
            int u, v, down, up;
            scanf("%d%d%d%d",&u,&v,&down,&up);
            addedge(u,v,up-down,0,i);
            du[u]-=down;
            du[v]+=down;
            dn[i]=down;
        }
        Edge=edge;
        for(int i=1; i<=n; i++)
        {
            if(du[i]>0) addedge(st,i,du[i],0,0);
            if(du[i]<0) addedge(i,sd,-du[i],0,0);
        }
        Dinic();
        bool flag=true;
        for(int i=head[st]; i>=0; i=Next[i])
            if(flow[i]>0)
            {
                flag=false;
                break;
            }
        if(!flag) puts("NO");
        else
        {
            puts("YES");
            for(int i=0; i<Edge; i++) ans[id[i]]=flow[i^1];
            for(int i=1; i<=m; i++)
                printf("%d\n",ans[i]+dn[i]);
        }
    }
    return 0;
}