关闭

poj 1459 Power Network SAP

206人阅读 评论(0) 收藏 举报
分类:

SAP的模板题,主要是输入有点难处理,看有人用sscanf函数处理的,我是直接对字符串进行处理的。

对于SAP:其实核心思想就是高度函数,把它搞懂SAP其实和EK算法本质上是一样的。

还有一个重要的是GAP优化,即当高度出现断层时算法结束。


#include<stdio.h>
#include<string.h>

const int N = 128;
const int INF = 0x3f3f3f3f;

struct Edge {
    int v, next;
    int c;
};
Edge edge[N*N<<2];
int h[N], numh[N], pre[N], curEdge[N];
int n, np, nc, m, cnt;
int fir[N];

void init() {
    cnt = 0;
    memset(fir, -1, sizeof(fir));
}

void addEdge(int u, int v, int c) {
    edge[cnt].v = v;
    edge[cnt].c = c;
    edge[cnt].next = fir[u];
    fir[u] = cnt++;
}

int SAP(int s, int e) {
    memset(h, 0, sizeof(h));
    memset(numh, 0, sizeof(numh));
    memset(pre, -1, sizeof(pre));
    for(int i = 0; i < n; i++)
        curEdge[i] = fir[i];
    numh[0] = n;
    int i;
    int cur = s, pos, mmin, maxflow = 0;
    while(h[s] < n) {
        if(cur == e) {
            mmin = INF;
            for(i = s; i != e; i = edge[curEdge[i]].v) {
                if(mmin > edge[curEdge[i]].c) {
                    mmin = edge[curEdge[i]].c;
                    pos = i;
                }
            }
;           for(i = s; i != e; i = edge[curEdge[i]].v) {
                edge[curEdge[i]].c -= mmin;
                edge[curEdge[i]^1].c += mmin;
            }
            maxflow += mmin;
            cur = pos;
        }
        for(i = curEdge[cur]; i != -1; i = edge[i].next)
            if(edge[i].c && h[cur] == h[edge[i].v] + 1)
                break;
        if(i != -1) {
            curEdge[cur] = i;
            pre[edge[i].v] = cur;
            cur = edge[i].v;
        } else {
            if(--numh[h[cur]] == 0) break;
            mmin = n;
            curEdge[cur] = fir[cur];
            for(i = fir[cur]; i != -1; i = edge[i].next) {
                if(edge[i].c && h[edge[i].v] < mmin)
                    mmin = h[edge[i].v];
            }
            h[cur] = mmin + 1;
            numh[h[cur]] ++;
            if(cur != s) cur = pre[cur];
        }
    }
    return maxflow;
}

int main() {

    char in[16];
    while(~scanf("%d%d%d%d", &n, &np, &nc, &m)) {
        int a, b, c;
        init();
        for(int i = 0; i < m; i++) {
            scanf("%s", in);
            a = b = c = 0;
            int bas = 1;
            int len = strlen(in);
            while(in[--len] != ')') {
                c += (in[len] - '0') * bas;
                bas *= 10;
            }
            bas = 1;
            while(in[--len] != ',') {
                b += (in[len] - '0') * bas;
                bas *= 10;
            }

            bas = 1;
            while(in[--len] != '(') {
                a += (in[len] - '0') * bas;
                bas *= 10;
            }
            addEdge(a, b, c);
            addEdge(b, a, 0);
        }
        for(int i = 0; i < np; i++) {
            scanf("%s", in);
            a = c = 0;
            int len = strlen(in);
            int bas = 1;
            while(in[--len] != ')') {

                c += (in[len] - '0') * bas;
                bas *= 10;
            }
            bas = 1;
            while(in[--len] != '(') {
                a += (in[len] - '0') * bas;
                bas *= 10;
            }
            addEdge(n, a, c);
            addEdge(a, n, 0);
        }
        for(int i = 0; i < nc; i++) {
            scanf("%s", in);
            a = c = 0;
            int len = strlen(in);
            int bas = 1;
            while(in[--len] != ')') {
                c += (in[len] - '0') * bas;
                bas *= 10;
            }
            bas = 1;
            while(in[--len] != '(') {
                a += (in[len] - '0') * bas;
                bas *= 10;
            }
            addEdge(a, n+1, c);
            addEdge(n+1, a, 0);
        }
        n += 2;
        printf("%d\n", SAP(n-2, n-1));
    }
    return 0;
}


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:27088次
    • 积分:755
    • 等级:
    • 排名:千里之外
    • 原创:49篇
    • 转载:4篇
    • 译文:0篇
    • 评论:0条