zoukankan      html  css  js  c++  java
  • 网络最大流的(Edmond Karp)算法

    容量网络:在有向图D=(V,A),指定一个点为发点,记作 s,指定另一个点为收点,记作 t,其余点叫作中间点。对于A的每条弧(Vi,Ai),都对应一个权数 C ≥0,称为弧(Vi , Ai)的容量,将这样的赋权有向图叫作一个容量网络,记作D=(V,A,C)。

            这有点不好懂,我解释一下网络最大流的意思是,从s(源点)到t(汇点)需要通过n条路径也有可能有一条s和t直接相连的,每一条路径能通过的最大流量(容量网络)又不尽相同,我们要求的是从s到t的最大流量,如图:

    从1到4的路径有:(1)1—>4;(2)1—>2—>4;(3)1-->2-->3-->4

    (1)的最大流量显然是20;(2)的最大流量是20;(3)的最大流量是10;

    因为20+10+10(三条路径最大流量)<20+40(从1出发的最大流量);所以根据此图可以找到1到4的最大流为20+10+10=50;

    #include <iostream>
    #include <stdio.h>
    #include <algorithm>
    #include <string.h>
    #include <queue>
    using namespace std;
    const int MAX=1000000;
    int map[20][20],flow[20],pre[20],n,m;
    bool vis[20];
    int BFS()
    {
        int up;
        queue<int> q;
        vis[1]=1;
        memset(pre,-1,sizeof(pre));
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++)
            flow[i]=MAX;
        q.push(1);
        while(!q.empty())
        {
           up=q.front();
            q.pop();
            if(up==n)
                break;
            for(int i=1;i<=n;i++)
            {
                if(!vis[i]&&map[up][i]>0)
                {
                    vis[i]=1;
                    flow[i]=min(flow[up],map[up][i]);
                    pre[i]=up;
                    q.push(i);
                }
            }
        }
        if(!vis[n]||n==1)
            return -1;
        return flow[n];
    }
    int EK()
    {
        int d,maxflow=0,up,down;
        maxflow=0;
        while((d=BFS())!=-1)
        {
            maxflow+=d;
            down=n;
            while(down!=1)
            {
                up=pre[down];
                map[up][down]-=d;
                map[down][up]+=d;
                down=up;
            }
        }
        return maxflow;
    }
    int main()
    {
        int T,a,b,c,h=1,i;
        scanf("%d",&T);
        while(T--)
        {
            memset(map,0,sizeof(map));
            scanf("%d%d",&n,&m);
            for(i=1;i<=m;i++)
            {
                scanf("%d%d%d",&a,&b,&c);
                map[a][b]+=c;
            }
            printf("Case %d: %d
    ",h++,EK());
        }
        return 0;
    }

     

  • 相关阅读:
    Linux下的lds链接脚本详解
    STM32启动过程解读与跟踪验证
    STM32的启动过程分析
    STM32启动过程--启动文件--分析
    STM32之中断
    STM32F4XX启动文件分析
    Synergy CORTEX M 启动流程
    AT 指令和常见错误码
    Tomcat部署时war和war exploded区别
    C++虚函数表解析***
  • 原文地址:https://www.cnblogs.com/yuanbo123/p/4711349.html
Copyright © 2011-2022 走看看