您的位置:首页 > Web前端 > React

【无源汇点上下界最大流】[SGU194]Reactor Cooling

2016-01-12 14:15 567 查看
题目

分析:边的容量为上界-下界,d数组保存当前节点下界的入度-岀度的差。为了保证流量的平衡,当di>0是,入度减掉的l比岀度多,所以从超级源点向i连一条容量为di的边,否则,从i向超级汇点连一条容量为-di的边。

然后从SS到ST跑一次最大流即可。

[code]#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define MAXN 200
#define MAXM MAXN*MAXN
#define INF 0x7f7f7f7f
using namespace std;
deque<int>q;
void Read(int &x){
    char c;
    while(c=getchar(),c!=EOF)
        if(c>='0'&&c<='9'){
            x=c-'0';
            while(c=getchar(),c>='0'&&c<='9')
                x=x*10+c-'0';
            ungetc(c,stdin);
            return;
        }
}
int d[MAXN+10],n,m,l[MAXM+10],S,T,dist[MAXN+10],num,vd[MAXN+10],flow,tot;
struct node{
    int v,cap;
    node *next,*back;
}*adj[MAXN+10],edge[MAXM*2+10],*ecnt=edge,*epos[MAXM+10];
void addedge(int u,int v,int cap,int pos){
    node *p=++ecnt;
    p->v=v;
    p->cap=cap;
    epos[pos]=p;
    p->next=adj[u];
    adj[u]=p;
    p=p->back=++ecnt;
    p->back=ecnt-1;
    p->v=u;
    p->cap=0;
    p->next=adj[v];
    adj[v]=p;
}
void read(){
    Read(n),Read(m);
    T=n+1;
    int i,u,v,low,high;
    for(i=1;i<=m;i++){
        Read(u),Read(v),Read(low),Read(high);
        addedge(u,v,high-low,i);
        d[u]-=low;
        d[v]+=low;
        l[i]=low;
    }
    for(i=1;i<=n;i++)
        if(d[i]>0)
            addedge(S,i,d[i],0),tot+=d[i];
        else if(d[i]<0)
            addedge(i,T,-d[i],0);
}
int dfs(int u,int augu){
    if(u==T)
        return augu;
    int v,augv=0,delta,mind=num-1;
    for(node *p=adj[u];p;p=p->next){
        if(p->cap){
            v=p->v;
            if(dist[u]==dist[v]+1){
                delta=min(augu-augv,p->cap);
                delta=dfs(v,delta);
                augv+=delta;
                p->cap-=delta;
                p->back->cap+=delta;
                if(augu==augv||dist[S]==num)
                    return augv;
            }
            mind=min(mind,dist[v]);
        }
    }
    if(!augv){
        if(!--vd[dist[u]])
            dist[S]=num;
        dist[u]=mind+1;
        vd[dist[u]]++;
    }
    return augv;
}
void sap(){
    num=T+1;
    vd[0]=num;
    while(dist[S]<num)
        flow+=dfs(S,INF);
}
void print(){
    if(flow!=tot)
        puts("NO");
    else{
        puts("YES");
        for(int i=1;i<=m;i++)
            printf("%d\n",epos[i]->back->cap+l[i]);
    }
}
int main()
{
    read();
    sap();
    print();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: