网络最大流的(Edmond Karp)算法

原来一听到网络最大流啊,什么BFS,DFS的就感觉特别的陌生,也感觉特别的头疼,如今我终于要学习到这里了这也标志着我要真正的要学习算法和搞acm了,所以我更要努力的学习力求向上把它学好。

不废话了,这最大流问题通过我今天的学习和理解终于有点眉目了,我就做个随笔,首先了解一下容量网络,百度了一下:

        容量网络:在有向图D=(V,A),指定一个点为发点,记作         ,指定另一个点为收点,记作         ,其余点叫作中间点。对于A的每条弧(         ),都对应一个权数         ≥0,称为弧(         )的容量,将这样的赋权有向图叫作一个容量网络,记作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\n",h++,EK());
    }
    return 0;
}
时间: 2024-08-07 19:57:49

网络最大流的(Edmond Karp)算法的相关文章

算法模板——Dinic网络最大流 2

实现功能:同Dinic网络最大流 1 这个新的想法源于Dinic费用流算法... 在费用流算法里面,每次处理一条最短路,是通过spfa的过程中就记录下来,然后顺藤摸瓜处理一路 于是在这个里面我的最大流也采用这种模式,这样子有效避免的递归,防止了爆栈么么哒 1 type 2 point=^node; 3 node=record 4 g,w:longint; 5 next,anti:point; 6 end; 7 var 8 i,j,k,l,m,n,s,t,flow:longint; 9 a,e:a

网络最大流算法

网络最大流是指在一个网络流图中可以从源点流到汇点的最大的流量.求解网络最大流的常用算法可以分为增广路径算法和预推进算法.其中,预推进算法的理论复杂度优于增广路径算法,但是编码复杂度过高,且效率优势在很多时候并不是很明显,因此,经常使用的算法为增广路径算法.     增广路径算法主要有Fold-Fulkerson算法,Edmonds-Karp算法,Dinic算法,ISAP算法.其中,Fold-Fulkerson 是最基本的增广路径思想,不能算作严格的算法实现. 增广路径     增广路径算法的思想

Ural1109_Conference(二分图最大匹配/匈牙利算法/网络最大流)

解题报告 二分图第一题. 题目描述: 为了参加即将召开的会议,A国派出M位代表,B国派出N位代表,(N,M<=1000) 会议召开前,选出K队代表,每对代表必须一个是A国的,一个是B国的; 要求每一个代表要与另一方的一个代表联系,除了可以直接联系,也可以电话联系,求电话联系最少 思路: 电话联系最少就要使直接联系最大,又是一一匹配关系,就是二分图的最大匹配. 下面是匈牙利算法. #include <cstdio> #include <cstring> #include <

【算法】网络最大流 Dinic

Dinic的大体思路是和EK差不多的(其实很多算法的大体思路都一样),只不过Dinic在每次寻找增广路时先bfs一下,给每个点都加上一个等级,而规定:只有等级相邻的两个点之间才能走,那么在dfs时就会减掉很多无用因此不必要的道路 1 #include<algorithm> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdio> 5 #include<queue> 6 using na

【算法】网络最大流 EK

网络流是干嘛的?举一个例子: 在一个水上城市中,有很多小镇,之间有很多座桥连着,每一座桥因为制作材料不同最大载重不同,如果超过最大载重,桥就垮了,桥上的人就GG了,所以我们不能让这样的情况发生——即:每一条边的流量不能超过容量,我们再规定一个起点,一个终点,我们要从起点运货到终点,只有一次机会但可以同时走多条道路充分利用资源,最后求:最大运货量可以为多少? 这就是网络最大流问题,求某点到某点的最大流量. EK算法,网络流最朴素的算法,不断寻找增广路,再来回两遍减容量,加ans,容易理解: 1 #

网络最大流 dinic算法

一句话题意:给出一个网络图,以及其源点和汇点,求出其网络最大流 //dinic算法; //时间复杂度O(V^2E); #include<bits/stdc++.h> #define inf 999999 #define maxn 200000 using namespace std; int n,m,s,t; int ans=0; struct Edge { int to,next,w; }; struct Edge edge[maxn]; int head[maxn],val[maxn],p

网络最大流算法—Dinic算法及优化

前置知识 网络最大流入门 前言 Dinic在信息学奥赛中是一种最常用的求网络最大流的算法. 它凭借着思路直观,代码难度小,性能优越等优势,深受广大oier青睐 思想 $Dinic$算法属于增广路算法. 它的核心思想是:对于每一个点,对其所连的边进行增广,在增广的时候,每次增广“极大流” 这里有别于EK算法,EK算法是从边入手,而Dinic算法是从点入手 在增广的时候,对于一个点连出去的边都尝试进行增广,即多路增广 Dinic算法还引入了分层图这一概念,即对于$i$号节点,用$dis(i)$表示它

POJ--1149--PIGS【网络最大流】

链接:http://poj.org/problem?id=1149 题意:迈克有一个养猪场,有m个猪圈,每个猪圈都上了锁,但是迈克没有钥匙他不能打开猪圈,要买猪的顾客一个接一个来养猪场,每个人有一些猪圈的钥匙,他们要买一定数目的猪,如果顾客要来买猪,他们会提前告诉迈克:他们所拥有的钥匙数量及对应哪些猪圈.要购买的数量,这样迈克就能安排销售计划使卖出的猪最多. 当每个顾客来的时候,将那些他拥有钥匙的猪圈门全部打开,迈克从猪圈中卖出一些猪给他们,如果迈克愿意,他可以重新分配这些被打开的猪圈中的猪,当

poj1087 网络最大流

http://poj.org/problem?id=1087 Description You are in charge of setting up the press room for the inaugural meeting of the United Nations Internet eXecutive (UNIX), which has an international mandate to make the free flow of information and ideas on