SGU 176 Flow construction-上下界网络流

题目描述

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 100
#define INF 200000000

struct node{
    int v,c,b;
    node *next,*back;
}edge[MAXN*MAXN*2+1000],*adj[MAXN+10],*ecnt=&edge[0];

int n,m,du[MAXN+10],d[MAXN+10],vd[MAXN+10],e[MAXN*MAXN*2+1000],flow,tot,s,t,cnte;

void addedge(int u,int v,int c,int b)
{
   // printf("***%d %d %d %d\n",u,v,c,b);
    node *p=++ecnt; ++cnte;
    p->v=v;
    p->c=c,p->b=b;
    p->next=adj[u],p->back=ecnt+1;
    adj[u]=p;
    p=++ecnt; ++cnte;
    p->v=u;
    p->c=0,p->b=b;
    p->next=adj[v],p->back=ecnt-1;
    adj[v]=p;
}
void limitflow(int x,int y,int c,int b)
{
    addedge(x,y,c-b,b);
    du[x]-=b,du[y]+=b;
}
void read()
{
    int x,y,c,d;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d%d%d",&x,&y,&c,&d);
        if(!d) limitflow(x,y,c,0);
        else limitflow(x,y,c,c);
        e[i]=cnte;
    }
    //limitflow(n,1,INF,0);
    s=n+1,t=n+2;
    for(int i=1;i<=n;i++){
        if(du[i]>0) addedge(s,i,du[i],0),tot+=du[i];
        if(du[i]<0) addedge(i,t,-du[i],0);
    }
}
int aug(int u,int augc)
{
    int augco=augc,mind=t,delta,v;
    if(u==t)
        return augc;
    for(node *p=adj[u];p;p=p->next){
        v=p->v;
        if(p->c>0){
            if(d[u]==d[v]+1){
                delta=aug(v,min(augco,p->c));
                p->c-=delta;
                p->back->c+=delta;
                augco-=delta;
                if(d[s]>=t)
                    return augc-augco;
                if(!augco)
                    break;
            }
            mind=min(mind,d[v]);
        }
    }
    if(augco==augc){
        vd[d[u]]--;
        if(!vd[d[u]])
            d[s]=t;
        d[u]=mind+1;
        vd[d[u]]++;
    }
    return augc-augco;
}
void Isap()
{
    flow=0;
    memset(d,0,sizeof d);
    memset(vd,0,sizeof vd);
    vd[0]=t;
    while(d[s]<t)
        flow+=aug(s,INF);
}
void workout()
{
    printf("%d\n",flow);
    for(int i=1;i<m;i++)
        printf("%d ",edge[e[i]].c+edge[e[i]].b);
    printf("%d\n",edge[e[m]].c+edge[e[m]].b);
}
bool Judge()
{
    for(node *p=adj[s];p;p=p->next)
        if(p->c)
            return false;
    return true;
}
int main()
{
    read();
    Isap(); //万一有环,应该充分利用环之后再建立edge(n,1,INF,0)
    limitflow(n,1,INF,0);
    Isap();
    if(!Judge())
        printf("Impossible\n");
    else
        workout();
}
posted @ 2016-01-26 14:47  KatarinaYuan  阅读(151)  评论(0编辑  收藏  举报