sgu194. Reactor Cooling 无源汇上下界可行流

来源:互联网 发布:软件生命周期管理 编辑:程序博客网 时间:2024/05/01 22:17

开始学习上下界网络流


Part1:
无源汇上下界可行流
无源汇上下界可行流就是在一个流量网络中,没有源点和汇点,每条边有流量上下界,要求一种合法的方案,并保证流量守恒。
最初的想法是转换到最大流来做,令每条边的流量为rili,然后跑最大流。不过这样是不符合流量守恒的,我们考虑怎样让它守恒。
首先设立一个超级源点S和超级汇点T
对于一个点u,定义du=l(i,u)l(u,j),那么分以下两种情况:
du>0,这意味着除去下界后我们流入的要小于流出的,因此连边(S,u,du)
du<0,这意味着除去下界后我们流入的要大于流出的,因此连边(u,Tdu)
然后跑一下最大流,观察是否满流。

#include<iostream>#include<cstdio>#include<cstring>#define inf 1000000007#define N 205#define M 80005using namespace std;int n,m,cnt,S,T,sigma;int head[N],dis[N],q[N],du[N],cur[N];int down[M>>1],next[M],key[M],list[M];inline int read(){    int a=0,f=1; char c=getchar();    while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}    while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}    return a*f;}inline void insert(int x,int y,int z){    next[++cnt]=head[x];    head[x]=cnt;    list[cnt]=y;    key[cnt]=z;}inline bool BFS(){    int t=0,w=1,x;    memset(dis,-1,sizeof(dis));    q[1]=0; dis[0]=1;    while (t<w)    {        x=q[++t];        for (int i=head[x];i;i=next[i])            if (key[i]&&dis[list[i]]==-1)                dis[q[++w]=list[i]]=dis[x]+1;    }    return dis[T]!=-1;}int find(int x,int flow){    if (x==T) return flow;    int w,used=0;    for (int i=cur[x];i;i=next[i])        if (key[i]&&dis[list[i]]==dis[x]+1)        {            w=find(list[i],min(key[i],flow-used));            key[i]-=w; key[i^1]+=w; used+=w;            if (key[i]) cur[x]=i;            if (used==flow) return used;        }    if (!used) dis[x]=-1;    return used;}inline int dinic(){    int ans=0;    while (BFS())    {        for (int i=0;i<=T;i++) cur[i]=head[i];        ans+=find(S,inf);    }    return ans;}int main(){    n=read(); m=read(); S=0; T=n+1; cnt=1;    for (int i=1;i<=m;i++)    {        int u=read(),v=read(),l=read(),r=read();        insert(u,v,r-l); insert(v,u,0);        du[u]-=l; du[v]+=l; down[i]=l;    }    for (int i=1;i<=n;i++)        if (du[i]>0) sigma+=du[i],insert(S,i,du[i]),insert(i,S,0);        else if (du[i]<0) insert(i,T,-du[i]),insert(T,i,0);    if (dinic()!=sigma) {puts("NO"); return 0;}    else    {        puts("YES");        for (int i=1;i<=m;i++) printf("%d\n",key[i<<1|1]+down[i]);    }    return 0;}   
0 0
原创粉丝点击