poj 1459 最大流

题意:总结点数 nodenum 电站数power 用户数consumer 电缆线数link

link个电缆:          (起点,终点) 最大传电量
power个电站:    (电站) 发电量
consume个用户:(用户) 用电量

分析:建超级源汇点,模板。。。

 

 

int NUM,FLAG;
#define DIG(a) (((a)>='0')&&((a)<='9'))
#define cini(j) {   \
    j=FLAG=0; NUM=getchar();   \
    while(!DIG(NUM)&&NUM!='-')NUM=getchar();   \
    if(NUM=='-'){FLAG=1;NUM=getchar();}   \
    j=NUM-'0';NUM=getchar();   \
    while(DIG(NUM)){j=10*j+(NUM-'0');NUM=getchar();}   \
    if(FLAG)j=-j;   \
}

#define M 105
int maze[M][M], n;
int gap[M], dis[M], pre[M], cur[M], d[M];

void bfs(int t){
    memset(dis, 1, sizeof(int)*n);
    memset(gap, 0, sizeof(int)*n);
    int que[M], tail=0, head=1;
    que[tail] = t;  dis[t]=0;   gap[0]=1;
    while(tail != head){
        int v = que[tail++];
        FOR(u, 0, n)
            if(maze[u][v] && dis[u] > dis[v]+1){
                dis[u] = dis[v]+1;
                gap[ dis[u] ] ++;
                que[head++] = u;
            }
    }
}

int sap(int s,int t,int n) {
    bfs(t);
    memset(cur,0,sizeof(int)*n);
    int u = pre[s] = s, maxflow = 0;
    d[s] = 0x7fffffff;
    while(dis[s] < n) {
        FOR(v,cur[u],n)
            if(maze[u][v] && dis[u] == dis[v] + 1) {
                d[v] = min(d[u], maze[u][v]);
                pre[v] = u;     u = cur[u] = v;
                if(v == t) {
                    int temp = s, flow = d[t];
                    maxflow += d[t];
                    for(u = pre[u];v != s;v = u,u = pre[u]) {
                        maze[u][v] -= flow;     maze[v][u] += flow;
                        d[v] -= flow;
                        if(d[v] && temp == s) temp = v;
                    }
                    u = temp;
                }
                v = cur[u]-1;//for循环中 v++后 v==cur[u]
            }
        if(!(--gap[ dis[u] ]))    break;
        dis[u] = n-1;
        FOR(v,0,n) if(maze[u][v] && dis[u]>dis[v]+1) {
            cur[u] = v;     dis[u] = dis[v]+1;
        }
        gap[dis[u]] ++;     u = pre[u];
    }
    return maxflow;
}


int sap2(int s,int t,int n) {
    MS(cur,0);MS(dis,0);MS(gap,0);
    int u = pre[s] = s,maxflow = 0;
    d[s] = 0x7fffffff;
    gap[0] = n;
    while(dis[s] < n) {
        FOR(v,cur[u],n)
            if(maze[u][v] && dis[u] == dis[v] + 1) {
                d[v] = min(d[u], maze[u][v]);
                pre[v] = u;     u = cur[u] = v;
                if(v == t) {
                    int temp = s, flow = d[t];
                    maxflow += d[t];
                    for(u = pre[u];v != s;v = u,u = pre[u]) {
                        maze[u][v] -= flow;     maze[v][u] += flow;
                        d[v] -= flow;
                        if(d[v] && temp == s) temp = v;
                    }
                    u = temp;
                }
                v = cur[u]-1;
            }
        if(!(--gap[ dis[u] ]))    break;
        dis[u] = n-1;
        FOR(v,0,n) if(maze[u][v] && dis[u]>dis[v]+1) {
            cur[u] = v;     dis[u] = dis[v]+1;
        }
        gap[dis[u]] ++;     u = pre[u];
    }
    return maxflow;
}

void build(){
    n+=2;
    FOR(i,0,n)memset(maze[i], 0, sizeof(int)*n);
    int power, consumer, link, a, b, c;
    cini(power); cini(consumer); cini(link);
    while(link--){
        cini(a); cini(b); cini(c);
        a++; b++;
        maze[a][b] = c;
    }
    while(power--){
        cini(a); cini(b);
        a++;
        maze[0][a] = b;
    }
    while(consumer--){
        cini(a); cini(b);
        a++;
        maze[a][n-1] = b;
    }
}

int main(){
    while(~scanf("%d",&n)){
        build();
        printf("%d\n",sap2(0,n-1,n));
    }
    return 0;
}

 

 

posted @ 2013-06-21 13:07  心向往之  阅读(164)  评论(0编辑  收藏  举报