SGU 194 【带上下界的无源汇的可行流】

题意:

给点数n和边数m。

接下来m条有向边。

a b c d 一次代表起点终点,下界上界。

求:

判断是否存在可行流,若存在则输出某可行流。否则输出IMPOSSIBLE

思路:

《一种简易的方法求解流量有上下界的网络中的网络流问题》

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<string.h>
#include<vector>
#define MAXN 4050
#define MAXM 40050
using namespace std;
const int inf=0x3f3f3f3f;
vector<pair<pair<int,int>,pair<int,int> > >jilu;
int inme[205],outme[205];
struct Edge
{
    int v,c,f,nx;
    Edge() {}
    Edge(int v,int c,int f,int nx):v(v),c(c),f(f),nx(nx) {}
} E[MAXM];
int G[MAXN],cur[MAXN],pre[MAXN],dis[MAXN],gap[MAXN],sz;
void init()
{
    sz=0;
    memset(G,-1,sizeof(G));
}
void add_edge(int u,int v,int c)
{
    E[sz]=Edge(v,c,0,G[u]);
    G[u]=sz++;
    E[sz]=Edge(u,0,0,G[v]);
    G[v]=sz++;
}
bool bfs(int S,int T)
{
    static int Q[MAXN];
    memset(dis,-1,sizeof(dis));
    dis[S]=0;
    Q[0]=S;
    for (int h=0,t=1,u,v,it; h<t; ++h)
    {
        for (u=Q[h],it=G[u]; ~it; it=E[it].nx)
        {
            if (dis[v=E[it].v]==-1&&E[it].c>E[it].f)
            {
                dis[v]=dis[u]+1;
                Q[t++]=v;
            }
        }
    }
    return dis[T]!=-1;
}
int dfs(int u,int T,int low)
{
    if (u==T) return low;
    int ret=0,tmp,v;
    for (int &it=cur[u]; ~it&&ret<low; it=E[it].nx)
    {
        if (dis[v=E[it].v]==dis[u]+1&&E[it].c>E[it].f)
        {
            if (tmp=dfs(v,T,min(low-ret,E[it].c-E[it].f)))
            {
                ret+=tmp;
                E[it].f+=tmp;
                E[it^1].f-=tmp;
            }
        }
    }
    if (!ret) dis[u]=-1;
    return ret;
}
int dinic(int S,int T)
{
    int maxflow=0,tmp;
    while (bfs(S,T))
    {
        memcpy(cur,G,sizeof(G));
        while (tmp=dfs(S,T,inf)) maxflow+=tmp;
    }
    return maxflow;
}
int main(){
    init();
    int n,m;
    scanf("%d%d",&n,&m);
    int a,b,c,d;
    for(int i=1;i<=m;i++){
        scanf("%d%d%d%d",&a,&b,&c,&d);
        add_edge(a,b,d-c);
        outme[a]+=c;
        inme[b]+=c;
        jilu.push_back(make_pair(make_pair(a,b),make_pair(c,d)));
    }
    for(int i=1;i<=n;i++){
        if(inme[i]-outme[i]>=0){
            add_edge(0,i,inme[i]-outme[i]);
        }
        else{
            add_edge(i,n+1,outme[i]-inme[i]);
        }
    }
    dinic(0,n+1);
    memcpy(cur,G,sizeof(G));
    int v;
    for(int i=1;i<=n;i++){
        if(inme[i]-outme[i]>=0){
            for (int it=cur[0]; ~it; it=E[it].nx){
                v=E[it].v;
                if(v==i){
                    if(E[it].f!=E[it].c){
                        puts("NO");
                        return 0;
                    }
                    break;
                }
            }
        }
        else{
            for(int it=cur[i];~it;it=E[it].nx){
                v=E[it].v;
                if(v==n+1){
                    if(E[it].f!=E[it].c){
                        puts("NO");
                        return 0;
                    }
                    break;
                }
            }
        }
    }
    puts("YES");
    for(int i=0;i<jilu.size();i++){
        a=jilu[i].first.first;
        b=jilu[i].first.second;
        c=jilu[i].second.first;
        for(int it=cur[a];~it;it=E[it].nx){
            v=E[it].v;
            if(v==b){
                printf("%d
",E[it].f+c);
                break;
            }
        }
    }
}
原文地址:https://www.cnblogs.com/tun117/p/5392448.html