网络流一·Ford-Fulkerson算法

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

小Hi和小Ho住在P市,P市是一个很大很大的城市,所以也面临着一个大城市都会遇到的问题:交通拥挤。

小Ho:每到周末回家感觉堵车都是一种煎熬啊。

小Hi:平时交通也还好,只是一到上下班的高峰期就会比较拥挤。

小Ho:要是能够限制一下车的数量就好了,不知道有没有办法可以知道交通系统的最大承受车流量,这样就可以限制到一个可以一直很顺畅的数量了。

小Hi:理论上是有算法的啦。早在1955年,T.E.哈里斯就提出在一个给定的网络上寻求两点间最大运输量的问题。并且由此产生了一个新的图论模型:网络流。

小Ho:那具体是啥?

小Hi:用数学的语言描述就是给定一个有向图G=(V,E),其中每一条边(u,v)均有一个非负数的容量值,记为c(u,v)≥0。同时在图中有两个特殊的顶点,源点S和汇点T。

举个例子:

其中节点1为源点S,节点6为汇点T。

我们要求从源点S到汇点T的最大可行流量,这个问题也被称为最大流问题。

在这个例子中最大流量为5,分别为:1→2→4→6,流量为1;1→3→4→6,流量为2;1→3→5→6,流量为2。

小Ho:看上去好像挺有意思的,你让我先想想。

提示:Ford-Fulkerson算法

输入

第1行:2个正整数N,M。2≤N≤500,1≤M≤20,000。

第2..M+1行:每行3个整数u,v,c(u,v),表示一条边(u,v)及其容量c(u,v)。1≤u,v≤N,0≤c(u,v)≤100。

给定的图中默认源点为1,汇点为N。可能有重复的边。

输出

第1行:1个整数,表示给定图G的最大流。

样例输入
6 7
1 2 3
1 3 5
2 4 1
3 4 2
3 5 3
4 6 4
5 6 2
样例输出
5
分析:最大流关键是求增广路,邻接表存边,便于修改;
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <list>
#define rep(i,m,n) for(i=m;i<=n;i++)
#define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++)
#define mod 1000000007
#define inf 0x3f3f3f3f
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ll long long
#define pi acos(-1.0)
#define pii pair<int,int>
#define Lson L, mid, rt<<1
#define Rson mid+1, R, rt<<1|1
const int maxn=5e2+;
using namespace std;
ll gcd(ll p,ll q){return q==?p:gcd(q,p%q);}
ll qpow(ll p,ll q){ll f=;while(q){if(q&)f=f*p;p=p*p;q>>=;}return f;}
int n,m,k,t,h[maxn],tot,p[maxn],a[maxn],v[maxn][maxn],ans;
struct node
{
int fr,to,nxt,cap,flow;
}e[<<];
void add(int x,int y,int z)
{
e[tot].fr=x;
e[tot].to=y;
e[tot].nxt=h[x];
e[tot].cap=z;
h[x]=tot++;
e[tot].fr=y;
e[tot].to=x;
e[tot].nxt=h[y];
h[y]=tot++;
}
void max_flow(int s,int t)
{
ans=;
while()
{
memset(a,,sizeof a);
queue<int>q;
q.push(s);a[s]=inf;
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=h[x];i!=-;i=e[i].nxt)
{
int to=e[i].to,cap=e[i].cap,flow=e[i].flow;
if(!a[to]&&cap>flow)
{
p[to]=i;
a[to]=min(a[x],cap-flow);
q.push(to);
}
}
if(a[t])break;
}
if(!a[t])break;
for(int now=t;now!=s;now=e[p[now]].fr)
{
e[p[now]].flow+=a[t];
e[p[now]^].flow-=a[t];
}
ans+=a[t];
}
}
int main()
{
int i,j;
scanf("%d%d",&n,&m);
memset(h,-,sizeof h);
while(m--)
{
int b,c,d;
scanf("%d%d%d",&b,&c,&d);
v[b][c]+=d;
}
rep(i,,n)rep(j,,n)if(v[i][j])add(i,j,v[i][j]);
max_flow(,n);
printf("%d\n",ans);
//system("Pause");
return ;
}
dicnic优化:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <list>
#define rep(i,m,n) for(i=m;i<=n;i++)
#define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++)
#define mod 1000000007
#define inf 0x3f3f3f3f
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ll long long
#define pi acos(-1.0)
#define pii pair<int,int>
#define Lson L, mid, rt<<1
#define Rson mid+1, R, rt<<1|1
const int maxn=5e2+;
using namespace std;
ll gcd(ll p,ll q){return q==?p:gcd(q,p%q);}
ll qpow(ll p,ll q){ll f=;while(q){if(q&)f=f*p;p=p*p;q>>=;}return f;}
int n,m,k,t,h[maxn],tot,vis[maxn],s,cur[maxn];
struct node
{
int fr,to,nxt,cap,flow;
}e[<<];
void add(int x,int y,int z)
{
e[tot].fr=x;
e[tot].to=y;
e[tot].nxt=h[x];
e[tot].cap=z;
h[x]=tot++;
e[tot].fr=y;
e[tot].to=x;
e[tot].nxt=h[y];
h[y]=tot++;
}
bool bfs()
{
memset(vis,,sizeof vis);
queue<int>p;
p.push(s);
vis[s]=;
while(!p.empty())
{
int x=p.front();p.pop();
for(int i=h[x];i!=-;i=e[i].nxt)
{
int to=e[i].to,cap=e[i].cap,flow=e[i].flow;
if(!vis[to]&&cap>flow)
{
vis[to]=vis[x]+;
p.push(to);
}
}
}
return vis[t];
}
int dfs(int x,int a)
{
if(x==t||a==)return a;
int ans=,j;
for(int&i=cur[x];i!=-;i=e[i].nxt)
{
int to=e[i].to,cap=e[i].cap,flow=e[i].flow;
if(vis[to]==vis[x]+&&(j=dfs(to,min(a,cap-flow)))>)
{
e[i].flow+=j;
e[i^].flow-=j;
ans+=j;
a-=j;
if(a==)break;
}
}
return ans;
}
int max_flow(int s,int t)
{
int flow=,i;
while(bfs())
{
rep(i,,n)cur[i]=h[i];
flow+=dfs(s,inf);
}
return flow;
}
int main()
{
int i,j;
memset(h,-,sizeof h);
scanf("%d%d",&n,&m);
while(m--)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
}
s=,t=n;
printf("%d\n",max_flow(s,t));
//system("Pause");
return ;
}

hihocoder网络流一·Ford-Fulkerson算法的更多相关文章

  1. ACM/ICPC 之 网络流入门-Ford Fulkerson与SAP算法(POJ1149-POJ1273)

    第一题:按顾客访问猪圈的顺序依次构图(顾客为结点),汇点->第一个顾客->第二个顾客->...->汇点 //第一道网络流 //Ford-Fulkerson //Time:47M ...

  2. 网络流-最大流问题 ISAP 算法解释(转自Renfei Song's Blog)

    网络流-最大流问题 ISAP 算法解释 August 7, 2013 / 编程指南 ISAP 是图论求最大流的算法之一,它很好的平衡了运行时间和程序复杂度之间的关系,因此非常常用. 约定 我们使用邻接 ...

  3. HDU3549 Flow Problem(网络流增广路算法)

    题目链接. 分析: 网络流增广路算法模板题.http://www.cnblogs.com/tanhehe/p/3234248.html AC代码: #include <iostream> ...

  4. POJ 2455 网络流 基础题 二分+网络流 dicnic 以及 sap算法

    Secret Milking Machine Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8189   Accepted: ...

  5. hihocoder 网络流二·最大流最小割定理

    网络流二·最大流最小割定理 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi:在上一周的Hiho一下中我们初步讲解了网络流的概念以及常规解法,小Ho你还记得内容么? ...

  6. 网络流入门--最大流算法Dicnic 算法

    感谢WHD的大力支持 最早知道网络流的内容便是最大流问题,最大流问题很好理解: 解释一定要通俗! 如右图所示,有一个管道系统,节点{1,2,3,4},有向管道{A,B,C,D,E},即有向图一张.  ...

  7. hihoCoder 网络流四·最小路径覆盖

    题面带解释 hihoCoder感觉很好. 网络流的精华就是建图 #include<cstdio> #include<iostream> #include<algorith ...

  8. 网络流的$\mathfrak{Dinic}$算法

    网络流想必大家都知道,在这不过多赘述.网络流中有一类问题是让你求最大流,关于这个问题,许多计算机学家给出了许多不同的算法,在这里--正如标题所说--我们只介绍其中的一种--\(\tt{Dinic}\) ...

  9. 网络流之最大流算法(EK算法和Dinc算法)

    最大流 网络流的定义: 在一个网络(有流量)中有两个特殊的点,一个是网络的源点(s),流量只出不进,一个是网络的汇点(t),流量只进不出. 最大流:就是求s-->t的最大流量 假设 u,v 两个 ...

随机推荐

  1. storage size of 'xxx' isn't known问题出现的可能原因之一

    storage size of 'value' isn't known问题出现的可能原因之一 有可能是头文件没有包含起来,所以会出现这种问题可以从以下几个方面来查找原因:1.若是结构体类型,类型是否写 ...

  2. C#连接ACCESS的一个问题

    C# 连接ACCESS数据库有时候报 "Microsoft.Jet.Oledb.4.0"没有注册,其实,并不是真的没注册,可能是下面的原因 在菜单 “项目”的最下面 工程属性 菜单 ...

  3. 网页特效-动态加载JavaScript

    描述: 把一些逻辑独立的JavaScript脚本文件单独加载,是一种常见的JavaScript动态加载技术.可以减少不必要的JavaScript脚本文件的加载,以提高网页浏览速度 代码: <!D ...

  4. java多维数组

    int a[][][] = {{{1,2},{1,2}},{{1,2},{1,2}}}; int b[][][] = new int[][][]{{{1,2},{1,2}},{{1,2},{1,2}} ...

  5. Linux中seq命令的用法

    用于产生从某个数到另外一个数之间的所有整数 例一: # seq 1 10 结果是1 2 3 4 5 6 7 8 9 10 例二: #!/bin/bash for i in `seq 1 10`; do ...

  6. JavaScript shift() 方法

    http://www.w3school.com.cn/jsref/jsref_shift.asp 定义和用法 shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值. 语法 arr ...

  7. servlet第3讲(上集)----同一用户的不同页面共享数据

    1.方法综述 2.Cookie 3.sendRedict()方法     4.隐藏表单

  8. 简单Spring和mybatis整合配置文件

    <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.spr ...

  9. HTML+CSS D08浮动

    1. <html> <head> <title>div浮动</title> <style type="text/css"> ...

  10. log4j2.xml配置及例子

    1.使用log4j2需要下载包,如下: 2.配置文件可以有三种格式(文件名必须规范,否则系统无法找到配置文件): classpath下名为 log4j-test.json 或者log4j-test.j ...