LOJ ා 115. Upper and lower bound feasible flow of passive sink

#115. Passive sink has upper and lower bound feasible flow

describe

This is a template problem.

n n n points, m m m edges, each edg e e e has a lower bound of flow (E) \ text {lower} (E) lower bound (E) and upper bound of flow (E) \ text {upper} (E) upper bound (E). A feasible scheme is found to make all edges meet the flow limit on the premise that all points meet the flow balance conditions.

Input format

In the first line, there are two positive integers, n n n, m m m M.

The next m m m lines are four integers s s s, t t t, lower \text{lower} lower, upper \text{upper} upper.

Output format

If there is NO solution, output a line of NO.

Otherwise, the first line will output YES, and then m m m lines will output an integer for each line, indicating the flow of each side.

Example

Sample input 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

Sample output 1

NO

Sample input 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

Sample output 2

YES
1
2
3
2
1
1

Data range and tips

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

Show category labels

 

The board questions, will not be detailed, free to sort out.

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
const int MAXN=2000001;
inline char nc()
{
    static char buf[MAXN],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
    char c=nc();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=nc();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=nc();}
    return x*f;
}
int n,m,s,t;
struct node
{
    int u,v,flow,nxt;
}edge[MAXN];
int head[MAXN],cur[MAXN],A[MAXN];
int num=0;
void AddEdge(int x,int y,int z)
{
    edge[num].u=x;
    edge[num].v=y;
    edge[num].flow=z;
    edge[num].nxt=head[x];
    head[x]=num++;
}
void add_edge(int x,int y,int z)
{
    AddEdge(x,y,z);
    AddEdge(y,x,0);
}
int deep[MAXN],L[MAXN];
bool BFS()
{
    memset(deep,0,sizeof(deep));
    deep[s]=1;
    queue<int>q;
    q.push(s);
    while(q.size()!=0)
    {
        int p=q.front();
        q.pop();
        for(int i=head[p];i!=-1;i=edge[i].nxt)
            if(!deep[edge[i].v]&&edge[i].flow)
            {
                deep[edge[i].v]=deep[edge[i].u]+1;q.push(edge[i].v);
                if(edge[i].v==t) return 1;
            }
                
    }
    return deep[t];
    
}
int DFS(int now,int nowflow)
{
    if(now==t||nowflow<=0)
        return nowflow;
    int totflow=0;
    for(int &i=cur[now];i!=-1;i=edge[i].nxt)
    {
        if(deep[edge[i].v]==deep[edge[i].u]+1&&edge[i].flow)
        {
            int canflow=DFS(edge[i].v,min(nowflow,edge[i].flow));
            edge[i].flow-=canflow;
            edge[i^1].flow+=canflow;
            totflow+=canflow;
            nowflow-=canflow;
            if(nowflow<=0)
                break;
        }
    }
    return totflow;
}
int Dinic()
{
    int ans=0;
    while(BFS())
    {
        for(int i=0;i<=n;i++)
            cur[i]=head[i];
        ans+=DFS(s,1e8);
    }
    return ans;
}
int main()
{
    #ifdef WIN32
    freopen("a.in","r",stdin);
    #else
    #endif
    n=read();m=read();s=0;t=n+1;
    memset(head,-1,sizeof(head));
    for(int i=1;i<=m;i++)
    {
        int x=read(),y=read(),lower=read(),upper=read();L[i-1]=lower;
        add_edge(x,y,upper-lower);A[x]-=lower;A[y]+=lower;
    }
    int sum=0;
    for(int i=1;i<=n;i++)
    {
        if(A[i]>0) sum+=A[i],add_edge(s,i,A[i]);
        else add_edge(i,t,-A[i]);
    }
    if(Dinic()!=sum) printf("NO");
    else
    {
        printf("YES\n");
        for(int i=0;i<m;i++)
            printf("%d\n",edge[i*2|1].flow+L[i]);
    }
    return  0;
}

Tags: C++

Posted on Tue, 05 May 2020 10:58:38 -0400 by ishboo