EK算法(连接矩阵)

本文介绍了Edmonds-Karp算法,一种简单的网络流算法,详细阐述其原理和复杂度,并提供了一个清晰的实现示例。强调网络流在竞赛编程中的重要性,指出实际问题转化为网络流问题的关键。同时,提到了网络流在多个领域的广泛应用,并提供了相关练习题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
    Edmonds-Karp算法是最简单的网络流算法,当然也比较慢复杂度为O(V*E^2)
    编写简单而且很好理解。。后面还会贴最快的dinic 算法
    复杂度为O(E*V^2)  ( E为边数,V为点数)

    网络流是个大学科,实在变化莫测,各种建图技巧,可以说竞赛考网络流
    90%考建图,图建好了,直接套模板即可

    这里只是简单的网络流模板而已
    真正的学问是把实际问题转换为网络流问题

    百度百科里这样描述网络流:
    网络流 network flows网络流的理论和应用在不断发展,出现了具有增益的流、
    多终端流、多商品流以及网络流的分解与合成等新课题。网络流的应用已遍及
    通讯、运输、电力、工程规划、任务分派、设备更新以及计算机辅助设计等众多领域。

    据我所知:甚至炒股问题也可以转换为网络流来搞

    由于我也只是能看懂模板套模板而已,真正对流的理解甚微,所以就不多说了,
    网络流在竞赛中很常见,属于重点内容,图中的一大分支,要引起足够的重视

*/
//由于我是用手敲的,只做参考,还请自行严格测试

const int inf = 0x3f3f3f3f;
const int M = 100;  // 结点数

int map[M][M], ans, n;  //ans 为最大流, n为节点个数
int pre[M], que[M], vis[M];

bool bfs(int s, int t) {  //源点为s, 汇点为t
    int head=0, tail=1;
    memset(vis, 0, sizeof(vis));
    que[0] = s;         //加入源点
    vis[s] = true;
    while (tail > head) {
        int u = que[head++];
        for (int i=0; i<=n; i++) {
            if (!vis[i] && map[u][i]) {
                pre[i] = u;  //前驱节点
                if (i == t)  //到达汇点
                    return true;
                que[tail++] = i;
                vis[i] = true;
            }
        }
    }
    return false;
}

void end(int s, int t) {
    int i, sum = inf;
    for (i=t; i!=s; i=pre[i])
        sum = min(sum, map[pre[i]][i]);
    for (i=t; i!=s; i=pre[i]) {
        map[pre[i]][i] -= sum;
        map[i][pre[i]] += sum;
    }
    ans += sum;
}

void EK(int s, int t) { //调用EK()即可,nv 为节点总数
    while (bfs(int s, int t))
        end(int s, int t);
}

/**
    注意:
    1、网络流问题属于有向图问题,可是我见过无向图的题目,
       直接按无向图添边即可,如果不行就用链接表存边,后面会贴,
       不过如果遇到最小费的无向图问题就必须用链接表了
    2、如有多个源点汇点,一般用0做源点,n+1做汇点,添无限容量边
    3、map[][] 数组只能用一次, ans赋初值为0
    4、最大流等于最小割,网络流还可以解决二分图匹配问题

    上面模板为依然空间的模板,也是最好理解的一个模板,
    依然的代码风格和我很类似,所以好多东西都抄袭他的,嘿嘿

    练习:POJ 1149 3281 1273  1459
*/

收藏于 2011-11-20
来自于百度空间

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值