poj 1459 网络流isap和EK的比较

poj 1459 网络流isap和EK的比较
http://hi.baidu.com/hust_pineapple/blog/item/3423eaf2374db0036c22eb40.html

先看isap的,这个是加了间隙优化的版本

 

Source Code

Problem: 1459 User: forgotaboutdre
Memory: 948K Time: 94MS
Language: G++ Result: Accepted

 

所谓间隙优化即指当某一个距离标号的数目为0时即返回当前流量。循环停止。

#include<cstdio>

#include<cstring>

#define size 270

#define inf 0x7ffff

int num[size], dis[size], pre[size];

int map[size][size], fanmap[size][size];

int n,np,nc,m;

int s, t;

int que[size];

 

int minc(int a, int b) {

    if (a <= b)

        return a;

    return b;

}

 

void bfs(int t) {

    memset(dis, 0, sizeof (dis));

    memset(num,0,sizeof(num));

    int head = 0, tail = 0;

    que[head] = t;

    num[0]=1;

    while (head <= tail) {

        int x = que[head];

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

            if (!dis[i] && map[i][x]) {

                dis[i] = dis[x] + 1;

                num[dis[i]]++;

                que[++tail] = i;

                if (i == s)

                    break;

            }

        head++;

    }

}

 

int findalowarc(int i) {

    for (int j = 0; j <= n+1; j++)

        if (map[i][j]>0 && dis[i] == dis[j] + 1)

            return j;

    return -1;

}

 

int retreat(int i) {

    int temp = inf;

    for (int j = 0; j <= n+1; j++)

        if (map[i][j] )

            temp = minc(dis[j] + 1, temp);

    if (temp != inf)

        return temp;

    return n+2;

}

 

int sap2(int s, int t) {

    int flow=0,i=s,j;

    int delt;

    bfs(t);

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

    while (dis[s]<n+2) {

        if (findalowarc(i)>= 0) {

            j = findalowarc(i);

            pre[j] = i;

            i = j;

            if (i==t) {

                delt = inf;

                for (i = t; i != s; i = pre[i])

                    delt = minc(delt, map[pre[i]][i]);

                for (i = t; i != s; i = pre[i]) {

                    map[pre[i]][i] -= delt;

                    map[i][pre[i]] += delt;

                }

                flow+=delt;

            }

        }

        else

        {

            int x=retreat(i);

            num[dis[i]]--;

            num[x]++;

            if(num[dis[i]]==0) return flow;

            dis[i]=x;

           if(i!=s) i=pre[i];

        }

    }

    return flow;

}

 

int main()

{

    char temp[20];

   while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF)

   {

    memset(map,0,sizeof(map));

    s=n;

    t=n+1;

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

    {

        int u,v,cost;

        scanf("%s",temp);

        sscanf(temp,"(%d,%d)%d",&u,&v,&cost);

        map[u][v]+=cost;

 

    }

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

    {

        int u,c;

        scanf("%s",temp);

        sscanf(temp,"(%d)%d",&u,&c);

        map[s][u]+=c;

    }

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

    {

        int u,c;

        scanf("%s",temp);

        sscanf(temp,"(%d)%d",&u,&c);

        map[u][t]+=c;

    }

    int ans=sap2(s,t);

    printf("%d\n",ans);

   }

    return 0;

}

 

 

 

 

版本2,不加间隙优化。

但是初始数组用BFS初始化了。

Source Code

Problem: 1459 User: yaws
Memory: 724K Time: 157MS
Language: G++ Result: Accepted

#include<cstdio>

#include<cstring>

#define size 300

#define inf 0x7fffff

int dis[size], pre[size];

int map[size][size], fanmap[size][size];

int n, np, nc, m;

int s, t;

int que[size];

 

void bfs(int t) {

    memset(dis, 0, sizeof (dis));

    int head = 0, tail = 0;

    que[head] = t;

 

    while (head <= tail) {

        int x = que[head];

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

            if (!dis[i] && map[i][x]) {

                dis[i] = dis[x] + 1;

                que[++tail] = i;

                if (i == s)

                    break;

            }

        head++;

    }

}

 

int minc(int a, int b) {

    if (a <= b)

        return a;

    return b;

}

 

int findalowarc(int i) {

    for (int j = 0; j <= n + 1; j++)

        if (map[i][j] > 0 && dis[i] == dis[j] + 1)

            return j;

    return -1;

}

 

int retreat(int i) {

    int temp = inf;

    for (int j = 0; j <= n + 1; j++)

        if (map[i][j])

            temp = minc(dis[j] + 1, temp);

    if (temp != inf)

        return temp;

    return n + 2;

}

 

int sap(int s, int t) {

    int flow = 0, i = s, j;

    int delt;

    bfs(t);

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

    while (dis[s] < n + 2) {

        if (findalowarc(i) >= 0) {

            j = findalowarc(i);

            pre[j] = i;

            i = j;

            if (i == t) {

                delt = inf;

                for (i = t; i != s; i = pre[i])

                    delt = minc(delt, map[pre[i]][i]);

                for (i = t; i != s; i = pre[i]) {

                    map[pre[i]][i] -= delt;

                    map[i][pre[i]] += delt;

                }

                flow += delt;

            }

        } else {

            int x = retreat(i);

            dis[i] = x;

            if (i != s)

                i = pre[i];

        }

    }

    return flow;

}

 

int main() {

    char temp[20];

    while (scanf("%d%d%d%d", &n, &np, &nc, &m) != EOF) {

        memset(map, 0, sizeof (map));

        s = n;

        t = n + 1;

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

            int u, v, cost;

            scanf("%s", temp);

            sscanf(temp, "(%d,%d)%d", &u, &v, &cost);

            map[u][v] += cost;

 

        }

        for (int i = 0; i < np; i++) {

            int u, c;

            scanf("%s", temp);

            sscanf(temp, "(%d)%d", &u, &c);

            map[s][u] += c;

        }

        for (int i = 0; i < nc; i++) {

            int u, c;

            scanf("%s", temp);

            sscanf(temp, "(%d)%d", &u, &c);

            map[u][t] += c;

        }

        int ans = sap(s, t);

        printf("%d\n", ans);

    }

    return 0;

}

 

 

版本3    没有加间隙优化,dis数组没有用BFS初始化,全部设初值为0;

 

Source Code

Problem: 1459 User: yaws
Memory: 724K Time: 157MS
Language: G++ Result: Accepted

。。。竟然和BFS初始化的效率一样,吾吾吾吾吾吾吾吾吾吾吾吾吾吾吾。。。。。。。

 

#include<cstdio>

#include<cstring>

#define size 300

#define inf 0x7fffff

int dis[size], pre[size];

int map[size][size], fanmap[size][size];

int n, np, nc, m;

int s, t;

int que[size];

 

 

int minc(int a, int b) {

    if (a <= b)

        return a;

    return b;

}

 

int findalowarc(int i) {

    for (int j = 0; j <= n + 1; j++)

        if (map[i][j] > 0 && dis[i] == dis[j] + 1)

            return j;

    return -1;

}

 

int retreat(int i) {

    int temp = inf;

    for (int j = 0; j <= n + 1; j++)

        if (map[i][j])

            temp = minc(dis[j] + 1, temp);

    if (temp != inf)

        return temp;

    return n + 2;

}

 

int sap(int s, int t) {

    int flow = 0, i = s, j;

    int delt;

    memset(dis,0,sizeof(dis));

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

    while (dis[s] < n + 2) {

        if (findalowarc(i) >= 0) {

            j = findalowarc(i);

            pre[j] = i;

            i = j;

            if (i == t) {

                delt = inf;

                for (i = t; i != s; i = pre[i])

                    delt = minc(delt, map[pre[i]][i]);

                for (i = t; i != s; i = pre[i]) {

                    map[pre[i]][i] -= delt;

                    map[i][pre[i]] += delt;

                }

                flow += delt;

            }

        } else {

            int x = retreat(i);

            dis[i] = x;

            if (i != s)

                i = pre[i];

        }

    }

    return flow;

}

 

int main() {

    char temp[20];

    while (scanf("%d%d%d%d", &n, &np, &nc, &m) != EOF) {

        memset(map, 0, sizeof (map));

        s = n;

        t = n + 1;

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

            int u, v, cost;

            scanf("%s", temp);

            sscanf(temp, "(%d,%d)%d", &u, &v, &cost);

            map[u][v] += cost;

 

        }

        for (int i = 0; i < np; i++) {

            int u, c;

            scanf("%s", temp);

            sscanf(temp, "(%d)%d", &u, &c);

            map[s][u] += c;

        }

        for (int i = 0; i < nc; i++) {

            int u, c;

            scanf("%s", temp);

            sscanf(temp, "(%d)%d", &u, &c);

            map[u][t] += c;

        }

        int ans = sap(s, t);

        printf("%d\n", ans);

    }

    return 0;

}

 

 

 

版本4

EK算法。。。。采用BFS寻找增广路,

 

 

Source Code

Problem: 1459 User: yaws
Memory: 524K Time: 313MS
Language: G++ Result: Accepted

 

 

 

 

#include<cstdio>

#include<cstring>

#define INF 100000

bool vis[250];

int map[205][205];

int que[1000];

int pre[205];

int n, np, nc, m, maxliu;

int s, t;

 

int minc(int a, int b) {

    if (a <= b)

        return a;

    return b;

}

 

bool bfs(int s, int t) {

    memset(vis, 0, sizeof (vis));

    int head = 0, tail = 0;

    que[head] = s;

    vis[s] = true;

    while (head <= tail) {

        int soce = que[head];

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

            if (!vis[i] && map[soce][i]) {

                que[++tail] = i;

                vis[i] = true;

                pre[i] = soce;

                if (i == t)

                    return true;

            }

        head++;

    }

    return 0;

}

 

void maxflam() {

    int limit = INF;

    for (int i = t; i != s; i = pre[i])

        limit = minc(limit, map[pre[i]][i]);

    for (int i = t; i != s; i = pre[i]) {

        map[pre[i]][i] -= limit;

        map[i][pre[i]] += limit;

    }

    maxliu += limit;

}

 

int main() {

    char temp[20];

    while (scanf("%d%d%d%d", &n, &np, &nc, &m) != EOF) {

        maxliu = 0;

        memset(map, 0, sizeof (map));

        s = n;

        t = n + 1;

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

            int u, v, cost;

            scanf("%s", temp);

            sscanf(temp, "(%d,%d)%d", &u, &v, &cost);

            map[u][v] += cost;

 

        }

        for (int i = 0; i < np; i++) {

            int u, c;

            scanf("%s", temp);

            sscanf(temp, "(%d)%d", &u, &c);

            map[s][u] += c;

        }

        for (int i = 0; i < nc; i++) {

            int u, c;

            scanf("%s", temp);

            sscanf(temp, "(%d)%d", &u, &c);

            map[u][t] += c;

        }

        while (bfs(s, t))

            maxflam();

        printf("%d\n", maxliu);

    }

    return 0;

}

 

总结:综上所述,sap算法的效率远高于EK,特别是加了间隙优化的sap,用BFS初始化距离标号其实没提高多少效率,可以忽略,反而能节省20行左右代码量。以后最大流就用sap吧。

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值