#115. 無源匯有上下界可行流(模板)

 

題目描述

這是一道模板題n  個點,m  條邊,每條邊 e  有一個流量下界 lower(e)(和流量上界 upper(e) ,求一種可行方案使得在全部點知足流量平衡條件的前提下,全部邊知足流量限制。html

輸入格式

第一行兩個正整數 n m node

以後的 m行,每行四個整數 s t lower upper c++

輸出格式

若是無解,輸出一行 NOui

不然第一行輸出 YES,以後 m 行每行一個整數,表示每條邊的流量。spa

樣例

樣例輸入 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 code

題解:

模板題;其實能夠就是經過某種建圖,而後取跑最大流,但是否滿流。htm

具體建圖方式: 創建源點S 匯點T, 每條邊創建 x ->y,flow=(最大流)-(最小流),同時創建每一個點流入流出狀況d[i],即d[x]-=流出,d[y]+=流入,輸出是最小流+跑完最大流後每條邊上的流量。blog

#include <bits/stdc++.h>
using namespace std;
const int MAXN=10200+10;
const int MAXM=10200+10;
const int INF=0x3f3f3f3f;
int ss,tt;
struct node{
    int v,next,flow;
}edge[MAXN*10];
int head[MAXN],cnt=0,cur[MAXN];
int d[MAXN],st[MAXM];
void ADD(int x,int y,int flow)
{
    edge[cnt].v=y;
    edge[cnt].flow=flow;
    edge[cnt].next=head[x];
    head[x]=cnt++;

    edge[cnt].v=x;
    edge[cnt].flow=0;
    edge[cnt].next=head[y];
    head[y]=cnt++;
}

int dis[MAXN];
bool bfs()
{
    memset(dis,-1, sizeof(dis));
    queue<int >qu;
    while(!qu.empty())
        qu.pop();
    qu.push(ss);
    dis[ss]=0;
    int u,v;
    while (!qu.empty())
    {
        u=qu.front();
        qu.pop();
        for (int i = head[u]; i !=-1 ; i=edge[i].next) {
            v=edge[i].v;
            if(dis[v]==-1&&edge[i].flow>0)
            {
                dis[v]=dis[u]+1;
                qu.push(v);
                if(v==tt)
                    break;
            }
        }
    }
    return dis[tt]!=-1;
}
int dfs(int u,int cap)
{
    if(u==tt||cap==0)
        return cap;
    int res=0,v,f;
    for (int &i = cur[u]; i !=-1; i=edge[i].next) {
        v=edge[i].v;
        if(dis[v]==dis[u]+1&&(f=dfs(v,min(cap-res,edge[i].flow)))>0)
        {
            edge[i].flow-=f;
            edge[i^1].flow+=f;
            res+=f;
            if(res==cap)
                return cap;
        }
    }
    if(!res)
        dis[u]=-1;
    return res;
}

int dinic()
{
    int ans=0;
    while(bfs())
    {
        for (int i = 0; i <=tt ; ++i) {
            cur[i]=head[i];
        }
        ans+=dfs(ss,INF);
    }
    return ans;
}



int main()
{
    int n,m;
    memset(head,-1, sizeof(head));
    memset(d,0, sizeof(d)); memset(st,0, sizeof(st));
    scanf("%d%d",&n,&m);
    ss=0;tt=n+1;
    int x,y,low,up;
    for (int i = 0; i <m ; ++i) {
        scanf("%d%d%d%d",&x,&y,&low,&up);
        ADD(x,y,up-low);
        d[x]-=low;
        d[y]+=low;
        st[i]=low;
    }
    int sum=0;
    for (int i = 1; i <=n ; ++i) {
        if(d[i]>0)
            sum+=d[i];
            ADD(ss,i,d[i]);
        if(d[i]<0)
            ADD(i,tt,-d[i]);
    }
    if(dinic()!=sum)
    {
        printf("NO\n");
        return 0;
    } else
    {
        printf("YES\n");
        for (int i = 0; i <m ; ++i) {
            printf("%d\n",edge[i*2|1].flow+st[i]);
        }
    }
    return 0;
}
//loj115
相關文章
相關標籤/搜索