上下界網絡流模板

T1 無源匯可行流 LYOI156

#include <bits/stdc++.h>
#define N 210
#define M 40010
#define INF INT_MAX
using namespace std;
int n,m,fir[N],nxt[M],to[M],flow[M],g[N],dis[N],q[N],lower[M],tot(1),s,t,e[M];

template <class Aqua>
inline void read(Aqua &s){
    s=0; char c=getchar();
    while (!isdigit(c)) c=getchar();
    while (isdigit(c)) s=s*10+(c^48),c=getchar();
}

inline void add(int u,int v,int x){
    to[++tot]=v; nxt[tot]=fir[u]; fir[u]=tot; flow[tot]=x;
    to[++tot]=u; nxt[tot]=fir[v]; fir[v]=tot; flow[tot]=0;
}

bool bfs(){
    for (int i=1;i<=n+2;i++)
        dis[i]=-1;
    dis[s]=0;
    q[1]=s;
    int l,r;
    for (l=r=1;l<=r;l++){
        for (int i=fir[q[l]];i;i=nxt[i])
            if (flow[i] && !~dis[to[i]]){
                dis[to[i]]=dis[q[l]]+1;
                if (to[i]==t)
                    return 1;
                q[++r]=to[i];
            }
    }
    return 0;
}

int dfs(int x,int limit){
    if (x==t) return limit;
    int f,tot(0),i;
    for (i=g[x];i;i=nxt[i])
        if (flow[i] && dis[x]+1==dis[to[i]]){
            f=dfs(to[i],min(limit-tot,flow[i]));
            tot+=f;
            flow[i]-=f;
            flow[i^1]+=f;
            if (tot==limit) break;
        }
    g[x]=i;
    if (tot<limit) dis[x]=-1;
    return tot;
}

int dinic(){
    int ans=0;
    while (bfs()){
        for (int i=1;i<=n+2;i++)
            g[i]=fir[i];
        ans+=dfs(s,INF);
    }
    return ans;
}

int main(){
    read(n),read(m);
    int u,v,x,y,sum(0);
    s=n+1,t=n+2;
    for (int i=1;i<=m;i++,sum+=x){
        read(u),read(v),read(x),read(y);
        add(u,v,y-x); e[i]=tot;
        out[u]+=x; in[v]+=x;
        lower[i]=x;
    }
    for (int i=1;i<=n;i++)
        add(i,t,out[i]),add(s,i,in[i]);
    if (dinic()!=sum)
        puts("NO");
    else{
        puts("YES");
        for (int i=1;i<=m;i++)
            printf("%d\n",flow[e[i]]+lower[i]);
    }
    return 0;
}

T2 有源匯最大流 LYOI157

注:其中ans_爲可行流。

#include <bits/stdc++.h>
#define N 210
#define M 80010
#define INF INT_MAX
using namespace std;
int n,m,fir[N],nxt[M],to[M],flow[M],g[N],dis[N],q[N],lower[M],tot(1),s,t,ans(0),s_,t_,in[N],out[N];

template <class Aqua>
inline void read(Aqua &s){
    s=0; char c=getchar();
    while (!isdigit(c)) c=getchar();
    while (isdigit(c)) s=s*10+(c^48),c=getchar();
}

inline void add(int u,int v,int x){
    to[++tot]=v; nxt[tot]=fir[u]; fir[u]=tot; flow[tot]=x;
    to[++tot]=u; nxt[tot]=fir[v]; fir[v]=tot; flow[tot]=0;
}

bool bfs(int s,int t){
    for (int i=1;i<=n+2;i++)
        dis[i]=-1;
    dis[s]=0;
    q[1]=s;
    int l,r;
    for (l=r=1;l<=r;l++){
        for (int i=fir[q[l]];i;i=nxt[i])
            if (flow[i] && !~dis[to[i]]){
                dis[to[i]]=dis[q[l]]+1;
                if (to[i]==t)
                    return 1;
                q[++r]=to[i];
            }
    }
    return 0;
}

int dfs(int x,int limit,int t){
    if (x==t) return limit;
    int f,tot(0),i;
    for (i=g[x];i;i=nxt[i])
        if (flow[i] && dis[x]+1==dis[to[i]]){
            f=dfs(to[i],min(limit-tot,flow[i]),t);
            tot+=f;
            flow[i]-=f;
            flow[i^1]+=f;
            if (tot==limit) break;
        }
    g[x]=i;
    if (tot<limit) dis[x]=-1;
    return tot;
}

void dinic(int s,int t){
    ans=0;
    while (bfs(s,t)){
        for (int i=1;i<=n+2;i++)
            g[i]=fir[i];
        ans+=dfs(s,INF,t);
    }
}

int main(){
    read(n),read(m),read(s_),read(t_);
    int u,v,x,y,sum(0);
    s=n+1,t=n+2;
    for (int i=1;i<=m;i++,sum+=x){
        read(u),read(v),read(x),read(y);
        add(u,v,y-x);
        out[u]+=x; in[v]+=x;
    }
    for (int i=1;i<=n;i++)
        add(i,t,out[i]),add(s,i,in[i]);
    add(t_,s_,INF);
    dinic(s,t);
    if (ans!=sum)
        puts("please go home to sleep");
    else{
        int ans_;
        for (int i=fir[t_];i;i=nxt[i])
            if (to[i]==s_)
                ans_=flow[i^1],flow[i]=flow[i^1]=0;
        dinic(s_,t_);
        printf("%d\n",ans_+ans);
    }
    return 0;
}

T2 有源匯最小流 LYOI158

#include <bits/stdc++.h>
#define N 50010
#define M 1000010
#define INF INT_MAX
using namespace std;
int n,m,fir[N],nxt[M],to[M],flow[M],g[N],dis[N],q[N],lower[M],tot(1),s,t,ans(0),s_,t_,in[N],out[N];

template <class Aqua>
inline void read(Aqua &s){
    s=0; char c=getchar();
    while (!isdigit(c)) c=getchar();
    while (isdigit(c)) s=s*10+(c^48),c=getchar();
}

inline void add(int u,int v,int x){
    to[++tot]=v; nxt[tot]=fir[u]; fir[u]=tot; flow[tot]=x;
    to[++tot]=u; nxt[tot]=fir[v]; fir[v]=tot; flow[tot]=0;
}

bool bfs(int s,int t){
    for (int i=1;i<=n+2;i++)
        dis[i]=-1;
    dis[s]=0;
    q[1]=s;
    int l,r;
    for (l=r=1;l<=r;l++){
        for (int i=fir[q[l]];i;i=nxt[i])
            if (flow[i] && !~dis[to[i]]){
                dis[to[i]]=dis[q[l]]+1;
                if (to[i]==t)
                    return 1;
                q[++r]=to[i];
            }
    }
    return 0;
}

int dfs(int x,int limit,int t){
    if (x==t) return limit;
    int f,tot(0),i;
    for (i=g[x];i;i=nxt[i])
        if (flow[i] && dis[x]+1==dis[to[i]]){
            f=dfs(to[i],min(limit-tot,flow[i]),t);
            tot+=f;
            flow[i]-=f;
            flow[i^1]+=f;
            if (tot==limit) break;
        }
    g[x]=i;
    if (tot<limit) dis[x]=-1;
    return tot;
}

void dinic(int s,int t){
    ans=0;
    while (bfs(s,t)){
        for (int i=1;i<=n+2;i++)
            g[i]=fir[i];
        ans+=dfs(s,INF,t);
    }
}

int main(){
    read(n),read(m),read(s_),read(t_);
    int u,v,x,y,sum(0);
    s=n+1,t=n+2;
    for (int i=1;i<=m;i++,sum+=x){
        read(u),read(v),read(x),read(y);
        add(u,v,y-x);
        out[u]+=x; in[v]+=x;
    }
    for (int i=1;i<=n;i++)
        add(i,t,out[i]),add(s,i,in[i]);
    add(t_,s_,INF);
    dinic(s,t);
    if (ans!=sum)
        puts("please go home to sleep");
    else{
        int ans_;
        for (int i=fir[t_];i;i=nxt[i])
            if (to[i]==s_)
                ans_=flow[i^1],flow[i]=flow[i^1]=0;
        dinic(t_,s_);
        printf("%d\n",ans_-ans);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章