网络流初步——增广路代码的分析

struct Edge
{
    int from,to,flow,cap;
    Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}
};
struct EdmonsKarp()
{
    int n,m;
    vector<Edge> edges;
    vector<int> G[maxn];
    int a[maxn];
    int p[maxn];

    void init(int n){
        for(int i=0;i<n;i++)
        G[i].clear();
        edges.clear();
    }
}

void AddEdge(int from,int to,int cap) //邻接表形式保存图 ,感谢耀神昨天的讲解,这个Edge明白了是邻接表的变形
{
    edges.push_back(Edge(from,to,cap,0));
    edges.push_back(Edge(to,from,0,0));
    m=edges.size();
    G[from].push_back(m-2);
    G[to].push_back(m-1);
}

int Maxflow(int s,int t)
{
    int flow=0;
    for(;;)
    {
        memset(a,0,sizeof(a));
        queue<int> Q;
        Q.push(s);
        a[s]=inf;
        while(!Q.empty())
        {                     //整个while循环用来找一条增广路当中的最小残余量
            int x=front();
                Q.pop();
            for(int i=0;i<G[x].size();i++)
            {
                Edge& e=G[x][i];
                if(!a[e.to]&&e.cap>e.flow)//每调用一条边,比较这条边的残量和其父节点的残量大小
                {                         //把最小残量保存到当前结点中
                a[e.to]=min(a[x],e.cap-e.flow);
                p[e.to]=G[x][i];          //p数组记录到当前结点的前一条边的编号
                Q.push(e.to);
                }
            }
            if(a[t])  //如果到达汇点了结束寻找
            break;
        if(!a[t]) //a数组肯定是一个全局变量,由于每调用一次这个函数只能求出一条增广路增加的量
        break;    //每次都把a[i]标记,所以当源结点的所有子节点都被标记后,自然到达不了汇点
        for(int u=t;u!=s;u=edges[p[u].from]) //而每一次函数调用后汇点都要被更新为0,所以当a[t]==0时候
        {                                    //就是所有的增广路都被跑完的时候
           edges[p[u]].flow+=a[t];
           edges[p[u]^1].flow-=a[t];
         }
         flow+=a[t];
         return flow;
    }
}

原文地址:https://www.cnblogs.com/rainyskywx/p/9975639.html

时间: 2024-08-27 11:16:13

网络流初步——增广路代码的分析的相关文章

网络流初步——增广路算法(EK)模板

1 #include <iostream> 2 #include <queue> 3 #include<string.h> 4 using namespace std; 5 #define arraysize 201 6 int maxData = 0x7fffffff; 7 int a[222][222]; 8 int flow[222]; 9 int pre[222]; 10 int n,m; 11 queue<int> q; 12 int BFS(in

最大流——增广路算法

关于网络流的增广路算法,网上有很多详细介绍,这里是摘录的模板.详细请见:http://www.cnblogs.com/kuangbin/archive/2011/07/26/2117636.html 1 #include<iostream> 2 #include<iomanip> 3 #include<ctime> 4 #include<climits> 5 #include<algorithm> 6 #include<queue>

关于最短增广路算法和连续最短增广路算法的操作步骤

最短增广路算法(SAP): 1.初始化容量网络和网络流: 2.构造残留网络和层次网络,如果汇点不在层次网络中,则算法结束: 3.在层次网络中不断用BFS增广,直到层次网络中没有增广路为止:每次增广完毕,在层次网络中要去掉因改进流量而导致饱和的弧: 4.转到步骤(2). 连续最短增广路算法(Dinic): 1.初始化容量网络和网络流: 2.构造残留网络和层次网络,如果汇点不在层次网络中,则算法结束: 3.在层次网络中用一次DFS过程进行增广,DFS执行完毕,该阶段的增广也执行完毕: 4.转到步骤(

Power Network(最大流基础_增广路算法:多源多汇,自建总源点和总汇点)

 Power NetworkCrawling in process... Crawling failed Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description A power network consists of nodes (power stations, consumers and dispatchers) connected by p

poj 1149 pigs 增广路 ford

题目关键是建模,之后就是简单地增广路. #include<stdio.h> #include<string.h> #include<algorithm> #include<vector> #include<queue> using namespace std; const int N=1024; const int inf=1<<24; struct { int c,f; }g[1024][1024]; int n,m,s,t; qu

Drainage Ditches(最大流基础_增广路算法)

 Drainage DitchesCrawling in process... Crawling failed Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description Every time it rains on Farmer John's fields, a pond forms over Bessie's favorite clover p

网络最大流增广路模板(EK &amp; Dinic)

EK算法: int fir[maxn]; int u[maxm],v[maxm],cap[maxm],flow[maxm],nex[maxm]; int e_max; int p[maxn],q[maxn],d[maxn]; void add_edge(int _u,int _v,int _w) { int e; e=e_max++; u[e]=_u;v[e]=_v;cap[e]=_w; nex[e]=fir[u[e]];fir[u[e]]=e; e=e_max++; u[e]=_v;v[e]=

增广路算法

#include<queue> #include<cstdio> #include<iostream> #include<cstring> using namespace std; const int maxn = 20; const int INF = (1<<30); int cap[maxn][maxn],flow[maxn][maxn];//cap记录容量,flow记录流量 int m; //弧的数量 int EdmondsKarp(in

最大网络流——增广路算法

几句废话:读了刘汝佳的书之后,感觉一切都是那么茫然,于是自己在网上找教程,自己一点点码的,大概用了三天.网络流基础:看来我很有必要说一下网络流的基础网络流问题就是给你一个图,每个图的边权叫做这条边的流量,问你从起始点出发,有多少值能通过这些边流到重点我知道你没看懂,举个例子: 如图: 最大值为 从1到2到4运6个 从1到2到3到4运1个 从1到3到4运3个 一共运10个. 举例说完了,那么我说几个定义: 容量,就只一条边的权值,表示能从这条边运送的最大值 流量,表示一条边实际上流过的最大值 那么