zoukankan      html  css  js  c++  java
  • 网络最大流模板(Edmonds-Karp算法)

    测试模板能不能过的——————题目链接

    邻接矩阵存图

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    
    const int inf = 0x3f3f3f3f;
    const int maxn = 10050;
    using namespace std;
    int n, m;
    int s, t;
    int maps[maxn][maxn], pre[maxn], flow[maxn], maxflow;
    //maps 邻接矩阵 pre[i] 记录增广路上的i点的前一个点 flow[i]表示从源点到该点的增广路上的可改进量
    
    
    int bfs()//用bfs去找增广路
    {
        queue <int> q;
        while(!q.empty())
            q.pop();
        for(int i=0; i<=n; i++)
            pre[i] = -1;
        pre[s] = 0;
        flow[s] = inf;
        q.push(s);
        while(!q.empty()){
            int x = q.front();
            q.pop();
            if(x == t)
                break;
            for(int i=1; i<=n; i++){
                if(maps[x][i]>0 && pre[i]==-1){
                    q.push(i);
                    pre[i] = x;//记录前置点
                    flow[i] = min(flow[x], maps[x][i]);//更新可改进量
                }
            }
        }
        if(pre[t] == -1)
            return -1;
        return flow[t];
    }
    
    void EK(){
        int a = bfs();
        while(a!=-1)//是否有增广路
        {
            //printf("%d****
    ", a);
            int k = t;
            while(k != s){
                int last = pre[k];
                //这里是一条 点last ---> 点k 的边
                maps[last][k] -= a;//前向弧
                maps[k][last] += a;//后向弧
                k = last;
            }
            maxflow += a;
            a = bfs();
        }
    }
    
    int main()
    {
        scanf("%d%d%d%d", &n, &m, &s, &t);
        for(int i=0; i<m; i++){
            int a, b, w;
            scanf("%d%d%d", &a, &b, &w);
            maps[a][b] += w;
        }
        EK();
        printf("%d
    ", maxflow);
        return 0;
    }
    

    邻接矩阵存图,只拿到了70分,有三个点MLE了
    不过这个还是很好写的



    邻接表(链式前向星实现)

    #include <bits/stdc++.h>
    const int maxn = 10050;
    const int inf = 0x3f3f3f3f;
    using namespace std;
    struct note{
        int u, v, w;
        int next;
    }e[maxn*20];	//边数开大点
    int head[maxn], cnt;
    int pre[maxn], vis[maxn];
    //pre[i] 记录的是增广路上的i点的前一条边在的e数组中的位置
    int n, m, s, t;
    
    void add(int u, int v, int w){
        e[cnt].u = u, e[cnt].v = v, e[cnt].w = w;
        e[cnt].next = head[u], head[u] = cnt++;
    	//建边建两条,是不是很像残留网络
        e[cnt].u = v, e[cnt].v = u, e[cnt].w = 0;
        e[cnt].next = head[v], head[v] = cnt++;
    }
    
    bool bfs(){//找增广路
        queue <int> q;
        memset(pre, -1, sizeof(pre));
        memset(vis, false, sizeof(vis));
        vis[s] = true;
        q.push(s);
        while(!q.empty()){
            int u = q.front();
            q.pop();
            for(int i=head[u]; ~i; i=e[i].next){
                int v = e[i].v;
                if(e[i].w>0 && !vis[v]){
                    pre[v] = i;
                    vis[v] = true;
                    if(v == t)//找到
                        return true;
                    q.push(v);
                }
            }
        }
        return false;
    
    }
    
    void EK()
    {
        int maxflow = 0;
        int a;
        while(bfs()){
            a = inf;
            int i = pre[t];
            while(~i){	//找适合的增量
                a = min(a, e[i].w);
                i = pre[e[i].u];
            }
            i = pre[t];
            while(~i){
                e[i].w -= a;	//想象下残留网络
                e[i^1].w += a;
                i = pre[e[i].u];
            }
            maxflow += a;
        }
        printf("%d
    ", maxflow);
    }
    
    int main()
    {
        memset(head, -1, sizeof(head));
        cnt = 0;
        scanf("%d%d%d%d", &n, &m, &s, &t);
        for(int i=0; i<m; i++){
            int a, b, w;
            scanf("%d%d%d", &a, &b, &w);
            add(a, b, w);
        }
        EK();
        return 0;
    }
    
    
  • 相关阅读:
    安卓证书获取sha1的方法 实测有效 原创!!!
    KafKa_原理及项目整合
    微服务-小结
    bd——kafka
    Zookeeper应用——
    idea使用小结
    服务管理框架——Zookeeper
    中间件汇总——了解
    新篇章:大数据——Flume
    70-71中期10道基石
  • 原文地址:https://www.cnblogs.com/jizhihong/p/13337359.html
Copyright © 2011-2022 走看看