hihocoder网络流一·Ford-Fulkerson算法
网络流一·Ford-Fulkerson算法
描述
小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:看上去好像挺有意思的,你让我先想想。
输入
第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算法的更多相关文章
- ACM/ICPC 之 网络流入门-Ford Fulkerson与SAP算法(POJ1149-POJ1273)
第一题:按顾客访问猪圈的顺序依次构图(顾客为结点),汇点->第一个顾客->第二个顾客->...->汇点 //第一道网络流 //Ford-Fulkerson //Time:47M ...
- 网络流-最大流问题 ISAP 算法解释(转自Renfei Song's Blog)
网络流-最大流问题 ISAP 算法解释 August 7, 2013 / 编程指南 ISAP 是图论求最大流的算法之一,它很好的平衡了运行时间和程序复杂度之间的关系,因此非常常用. 约定 我们使用邻接 ...
- HDU3549 Flow Problem(网络流增广路算法)
题目链接. 分析: 网络流增广路算法模板题.http://www.cnblogs.com/tanhehe/p/3234248.html AC代码: #include <iostream> ...
- POJ 2455 网络流 基础题 二分+网络流 dicnic 以及 sap算法
Secret Milking Machine Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8189 Accepted: ...
- hihocoder 网络流二·最大流最小割定理
网络流二·最大流最小割定理 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi:在上一周的Hiho一下中我们初步讲解了网络流的概念以及常规解法,小Ho你还记得内容么? ...
- 网络流入门--最大流算法Dicnic 算法
感谢WHD的大力支持 最早知道网络流的内容便是最大流问题,最大流问题很好理解: 解释一定要通俗! 如右图所示,有一个管道系统,节点{1,2,3,4},有向管道{A,B,C,D,E},即有向图一张. ...
- hihoCoder 网络流四·最小路径覆盖
题面带解释 hihoCoder感觉很好. 网络流的精华就是建图 #include<cstdio> #include<iostream> #include<algorith ...
- 网络流的$\mathfrak{Dinic}$算法
网络流想必大家都知道,在这不过多赘述.网络流中有一类问题是让你求最大流,关于这个问题,许多计算机学家给出了许多不同的算法,在这里--正如标题所说--我们只介绍其中的一种--\(\tt{Dinic}\) ...
- 网络流之最大流算法(EK算法和Dinc算法)
最大流 网络流的定义: 在一个网络(有流量)中有两个特殊的点,一个是网络的源点(s),流量只出不进,一个是网络的汇点(t),流量只进不出. 最大流:就是求s-->t的最大流量 假设 u,v 两个 ...
随机推荐
- javaWEB总结(2): load-on-startup节点
在javaWEB总结(1)里面,我们创建了一个servlet以及它的映射,当我们访问那个映射地址的时候,就可以访问servlet,并且servlet容器调用了生命周期方法,销毁前调用destroy方法 ...
- Java heap space
//首先检查程序有没有限入死循环 这个问题主要还是由这个问题 java.lang.OutOfMemoryError: Java heap space 引起的.第一次出现这样的的问题以后,引发了其他的问 ...
- java操作cookies
建立一个无生命周期的cookie,即随着浏览器的关闭即消失的cookie,代码如下 HttpServletRequest request HttpServletResponse response Co ...
- leetcode404-----简单的树的遍历
Find the sum of all left leaves in a given binary tree. Example: 3 / \ 9 20 / \ 15 7 There are two l ...
- csu1010: Water Drinking
/* 本题的题意: 沙漠中有很多骆驼和一个池塘,0表示池塘,1-N表示骆驼,输入的两个数表示两只骆驼,其中前面的那一头靠近池塘,所有的骆驼队列不交叉不相连,求站在队尾但是离水井最近的骆驼编号 经过分析 ...
- getuid和geteuid的区别
getuid() : 函数返回一个调用程序的真实用户ID.表明当前运行位置程序的执行者. geteuid(): 函数返回返回一个有效用户的ID.(EUID)是你最初执行程序时所用的ID,该ID是程序 ...
- jsoup抓取数据
jsoup的主要功能如下: 1. 从一个URL,文件或字符串中解析HTML: 2. 使用DOM或CSS选择器来查找.取出数据: 3. 可操作HTML元素.属性.文本: 接下来介绍jsoup 是如何优雅 ...
- C#操作SQLite 报错 (Attempt to write a read-only database)
解决办法:找到SQLite数据库所在的文件夹,单击右键,属性->安全,为Users用户组添加写入权限.
- git 查看当前与上一次version的差异
http://stackoverflow.com/questions/9903541/finding-diff-between-current-and-last-versions up vote47d ...
- linux跨主机复制文件或文件夹
复制文件基本格式:(本地到远程) scp 文件名 用户名@ip:文件全目录 如果是文件夹加上参数 -r scp -r 基础目录 用户名@ip:目录 栗子: scp local_file remote_ ...