zoj 2314 Reactor Cooling

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1314

大牛就是大牛  人家能想到咱就是想不到呀

根据所给流量下限(下限必流)

记录每个点的入度(in) 和出度(out)  然后用(上限-下限)进行建图 (这是还可以增加的流)

然后虚拟起点和汇点  根据每个点的 in 和 out 

如果 in > out 说明此点需要流出(in - out ) 然后从起点连一条边 流为( in - out ) 等于给此点一个流出的机会

如果 in < out 说明此点需要流入 (out - in ) 然后向终点连一条边 流为 ( out - in ) 等于给此点一个流入的机会

然后求最大流  看是否最大流为满流(既等于初始化时从起点需要流出的量 且等于初始化时需要向汇点流入的量)

代码:

#include<iostream>

#include<cstdio>

#include<cstring>

#include<string>

#include<algorithm>

#include<cmath>

#include<map>

#include<set>

#include<vector>

#include<stack>

#include<queue>

//#pragma comment(linker, "/STACK:1024000000,1024000000")

#define ll long long



using namespace std;

const int INF=0x3f3f3f3f;

const int MOD=100000007;

const int N=205;

const int M=100005;

int head[N],I;

struct node

{

    int j,next;

    int k;

    int flow;

}edge[M];

struct node1

{

    int l,r,low,high;

}p[M];

int in[N],out[N];

int L[N];

int st,nd;

void add(int i,int j,int flow,int k)

{

    edge[I].j=j;

    edge[I].k=k;

    edge[I].flow=flow;

    edge[I].next=head[i];

    head[i]=I++;

}

bool bfs(int x1,int x2)

{

    memset(L,-1,sizeof(L));

    queue<int>qt;

    qt.push(x1);

    L[x1]=0;

    while(!qt.empty())

    {

        int x=qt.front();

        qt.pop();

        for(int t=head[x];t!=-1;t=edge[t].next)

        {

            int j=edge[t].j;

            if(edge[t^1].flow>0&&L[j]==-1)

            {

                L[j]=L[x]+1;

                qt.push(j);

            }

        }

    }

    if(L[x2]==-1)

    return false;

    return true;

}

int dfs(int x,int sum)

{

    if(x==nd)

    return sum;

    int tmp=sum;

    for(int t=head[x];t!=-1;t=edge[t].next)

    {

        int j=edge[t].j;

        if(edge[t].flow>0&&L[x]==L[j]+1)

        {

            int w=dfs(j,min(tmp,edge[t].flow));

            edge[t].flow-=w;int k=edge[t].k;if(k!=-1)p[k].low+=w;

            edge[t^1].flow+=w;k=edge[t^1].k;if(k!=-1)p[k].low-=w;

            tmp-=w;

            if(tmp==0)

            break;

        }

    }

    return (sum-tmp);

}

void init(int n,int m,int st,int nd,int &S,int &E)

{

    memset(in,0,sizeof(in));

    memset(out,0,sizeof(out));

    for(int i=0;i<m;++i)

    {

        cin>>p[i].l>>p[i].r>>p[i].low>>p[i].high;

        out[p[i].l]+=p[i].low;

        in[p[i].r]+=p[i].low;

        add(p[i].l,p[i].r,p[i].high-p[i].low,i);

        add(p[i].r,p[i].l,0,-1);

    }

    for(int i=1;i<=n;++i)

    {

        if(in[i]>out[i])

        {

            add(st,i,in[i]-out[i],-1);

            add(i,st,0,-1);

            S+=(in[i]-out[i]);

        }

        if(in[i]<out[i])

        {

            add(i,nd,out[i]-in[i],-1);

            add(nd,i,0,-1);

            E+=(out[i]-in[i]);

        }

    }

}

int main()

{

    //freopen("data.in","r",stdin);

    int T;

    cin>>T;

    while(T--)

    {

        int n,m;

        while(cin>>n>>m)//cout<<n<<m<<endl;

        {

            memset(head,-1,sizeof(head));

            I=0;

            st=0;

            nd=n+1;

            int S=0,E=0;

            init(n,m,st,nd,S,E);//cout<<S<<" "<<E<<endl;

            int ans=0;

            while(bfs(nd,st))

            {

                int k;

                while((k=dfs(st,INF)))

                ans+=k;

            }

            //cout<<ans<<" "<<S<<" "<<E<<endl;

            if(S==ans&&E==ans)

            {

                cout<<"YES"<<endl;

                for(int i=0;i<m;++i)

                cout<<p[i].low<<endl;

            }

            else

            {

                cout<<"NO"<<endl;

            }

        }

    }

    return 0;

}

  

你可能感兴趣的:(react)