Problem Description

Network flow is a well-known difficult problem for ACMers. Given a graph, your task is to find out the maximum flow for the weighted directed graph.

Input

The first line of input contains an integer T, denoting the number of test cases.
For each test case, the first line contains two integers N and M, denoting the number of vertexes and edges in the graph. (2 <= N <= 15, 0 <= M <= 1000)
Next M lines, each line contains three integers X, Y and C, there is an edge from X to Y and the capacity of it is C. (1 <= X, Y <= N, 1 <= C <= 1000)

Output

For each test cases, you should output the maximum flow from source 1 to sink N.

Sample Input

2
3 2
1 2 1
2 3 1
3 3
1 2 1
2 3 1
1 3 1

Sample Output

Case 1: 1
Case 2: 2
解题思路:Dicic实现,即每个阶段先进行1次bfs给图分层,然后在该图上进行1次或多次寻找增广路,如果当前层次图中已找不到增广路,就重新给图分层,然后继续找增广路,只要t的level小于0就说明当前网络已达到最大流。时间复杂度大概为O(|E||V|2)。
AC代码一(312ms):
 #include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=;//int cnt=1;
struct edge{ int to, cap; size_t rev;
edge(int _to, int _cap, size_t _rev) :to(_to), cap(_cap), rev(_rev){}//构造函数,初始化结构体变量
};//指向节点to,边容量是cap,rev是记录为当前邻接点to反向边的编号
vector<edge> G[maxn];//邻接表,G[i][j]表示节点i连接的第j条边包含的所有信息
int t,n,m,x,y,c,level[maxn];//level数组在bfs时为分层图所用
void add_edge(int from,int to,int cap){//向图中增加一条从s到t容量为cap的边
G[from].push_back(edge( to, cap, G[to].size() ));
G[to].push_back(edge( from, , G[from].size() - ));//关键:反向建边,初始流量为0
}
//bfs给图分层次
void bfs(int s){
memset(level,-,sizeof(level));//刚开始每个节点的层次置为-1
queue<int> que;//队列实现bfs
level[s]=;//源点s为第0层
que.push(s);
while(!que.empty()){//给图分层
int v=que.front();que.pop();
for(size_t i=;i<G[v].size();++i){//遍历节点v与之相连的每条边
edge &e=G[v][i];//取出与节点v相连的第i条边
if(e.cap>&&level[e.to]<){//如果边残余流量大于0,且节点e.to还未分层
level[e.to]=level[v]+;//节点e.to的层次为指向它的节点v所在层次数加1
que.push(e.to);
}
}
}
}
//dfs寻找增广路,寻找当前图中s-->t的一条增广路
int dfs(int v,int t,int f){//v->t(t为汇点),当前增广路径上的最小剩余流量为f
if(v==t)return f;//到达汇点t
for(size_t i=;i<G[v].size();++i){//遍历节点v与之相连的每条边
edge &e=G[v][i];//取出与节点v相连的第i条边
if(e.cap> && level[v]<level[e.to]){//如果该边残流量大于0,且邻接点e.to是v的下一级,就增广下去
//cout<<"当前遍历到的点v:"<<v<<",邻接点to:"<<e.to<<endl;
int d=dfs(e.to,t,min(f,e.cap));//维护当前增广路上最小的剩余流量f
if(d>){//若f>0,说明找到了一条增广路
//cout<<v<<"-->"<<e.to<<",边容量为:"<<e.cap<<endl;
e.cap-=d;//正向边流量减去f
G[e.to][e.rev].cap+=d;//反向边流量加上f
return d;//沿着增广路回溯到源点s,不会在途中去深搜其他点,返回当前增广路上的最小剩余流量
}
}
}
return ;//否则说明没有增广路,返回0
}
//Dinic算法实现最大流,每个阶段执行完一次bfs分层之后,只需查找当前层次图中是否还增广路即可
int max_flow(int s,int t){
int flow=;
while(){
bfs(s);//每个阶段先bfs将图分层标记
if(level[t]<)return flow;
//如果分层之后,汇点t的层次小于0,即未被分层,说明再无增广路,则直接返回当前最大流量
int f=dfs(s,t,INF);
//cout<<"第"<<cnt++<<"次的最小剩余容量为:"<<f<<endl;
while(f>){//在该层次图中找到增广路
flow+=f;//累加到最大流中
f=dfs(s,t,INF);//继续找该层次图中是否还有增广路,直到f为0,
//cout<<"第"<<cnt++<<"次的最小剩余容量为:"<<f<<endl;
}
}
}
int main(){
while(~scanf("%d",&t)){
for(int cas=;cas<=t;++cas){
scanf("%d%d",&n,&m);//cnt=1;
for(int i=;i<=n;++i)G[i].clear();
while(m--){
scanf("%d%d%d",&x,&y,&c);
add_edge(x,y,c);
}
printf("Case %d: %d\n",cas,max_flow(,n));
}
}
return ;
}

AC代码二(93ms):当前弧优化Dinic算法。

 #include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=;
struct edge{ int to,cap;size_t rev;
edge(int _to, int _cap, size_t _rev):to(_to),cap(_cap),rev(_rev){}
};
int T,n,m,x,y,c,level[maxn];queue<int> que;vector<edge> G[maxn];size_t curfir[maxn];
void add_edge(int from,int to,int cap){
G[from].push_back(edge(to,cap,G[to].size()));
G[to].push_back(edge(from,,G[from].size()-));
}
bool bfs(int s,int t){
memset(level,-,sizeof(level));
while(!que.empty())que.pop();
level[s]=;
que.push(s);
while(!que.empty()){
int v=que.front();que.pop();
for(size_t i=;i<G[v].size();++i){
edge &e=G[v][i];
if(e.cap>&&level[e.to]<){
level[e.to]=level[v]+;
que.push(e.to);
}
}
}
return level[t]<?false:true;
}
int dfs(int v,int t,int f){
if(v==t)return f;
for(size_t &i=curfir[v];i<G[v].size();++i){
edge &e=G[v][i];
if(e.cap>&&(level[v]+==level[e.to])){
int d=dfs(e.to,t,min(f,e.cap));
if(d>){
e.cap-=d;
G[e.to][e.rev].cap+=d;
return d;
}
}
}
return ;
}
int max_flow(int s,int t){
int f,flow=;
while(bfs(s,t)){
memset(curfir,,sizeof(curfir));
while((f=dfs(s,t,INF))>)flow+=f;
}
return flow;
}
int main(){
while(~scanf("%d",&T)){
for(int cas=;cas<=T;++cas){
scanf("%d%d",&n,&m);
for(int i=;i<=n;++i)G[i].clear();
while(m--){
scanf("%d%d%d",&x,&y,&c);
add_edge(x,y,c);
}
printf("Case %d: %d\n",cas,max_flow(,n));
}
}
return ;
}

题解报告:hdu 3549 Flow Problem(最大流入门)的更多相关文章

  1. HDU 3549 Flow Problem(最大流)

    HDU 3549 Flow Problem(最大流) Time Limit: 5000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/ ...

  2. 网络流 HDU 3549 Flow Problem

    网络流 HDU 3549 Flow Problem 题目:pid=3549">http://acm.hdu.edu.cn/showproblem.php?pid=3549 用增广路算法 ...

  3. hdu 3549 Flow Problem

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=3549 Flow Problem Description Network flow is a well- ...

  4. hdu 3549 Flow Problem【最大流增广路入门模板题】

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=3549 Flow Problem Time Limit: 5000/5000 MS (Java/Others ...

  5. hdu 3549 Flow Problem (网络最大流)

    Flow Problem Time Limit: 5000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Tota ...

  6. hdu 3549 Flow Problem Edmonds_Karp算法求解最大流

    Flow Problem 题意:N个顶点M条边,(2 <= N <= 15, 0 <= M <= 1000)问从1到N的最大流量为多少? 分析:直接使用Edmonds_Karp ...

  7. HDU 3549 Flow Problem 网络流(最大流) FF EK

    Flow Problem Time Limit: 5000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Tot ...

  8. HDU 3549 Flow Problem (最大流ISAP)

    Flow Problem Time Limit: 5000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Tota ...

  9. hdu 3549 Flow Problem (Dinic)

    Flow ProblemTime Limit: 5000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total ...

  10. hdu 3549 Flow Problem 最大流问题 (模板题)

    Flow Problem Time Limit: 5000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Tota ...

随机推荐

  1. thinkphp Class 'PDO' not found 错误

    thinkphp Class 'PDO' not found 错误,原因mysql5.7.26缺少pdo驱动,需要安装php的pdo和pdo_mysql扩展 本文以centOS为例 1.进入PHP源码 ...

  2. 责任链模式-Chain of Responsibility

    责任链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. 责任链模式结构图: 代码实现: 责任链模式 ...

  3. YARN commands are invoked by the bin/yarn script.

    Apache Hadoop 2.9.0 – YARN Commands http://hadoop.apache.org/docs/stable/hadoop-yarn/hadoop-yarn-sit ...

  4. Sequelize入门一

    最近刚开始接触Sequelize,当中遇到不少坑,所以想写篇Sequelize入门和大家分享,避免有道友和我一样爬坑. 学习sequelize的初衷是想解决SQL注入,它支持MySQL, SQLite ...

  5. Mac开发必备工具(二)—— iTerm 2

    iTerm 2 简介 iTerm 2 is a terminal emulator for Mac OS X that does amazing things. iTerm 2 有很多能够提升效率的实 ...

  6. (linux)schedule_delayed_work()

      原文地址:schedule_delayed_work()用法作者:Valley   第一篇 工作队列       在Linux内核中,对下半部(或者说推后执行的工作)的处理方式有好几种,包括BH( ...

  7. GC回收算法

    GC回收算法 https://www.cnblogs.com/missOfAugust/p/9528166.html Java语言引入了垃圾回收机制,让C++语言中令人头疼的内存管理问题迎刃而解,使得 ...

  8. BZOJ_1563_[NOI2009]诗人小G_决策单调性

    BZOJ_1563_[NOI2009]诗人小G_决策单调性 Description Input Output 对于每组数据,若最小的不协调度不超过1018,则第一行一个数表示不协调度若最小的不协调度超 ...

  9. phpstorm 10 初体验

    一:安装phpstorm 10 去phpstorm 10官网下载,安装 https://www.jetbrains.com/phpstorm/ 按照提示安装,最后注册步骤,选择“License ser ...

  10. Linux和windows下执行sql脚本文件

    利用 sqlplus 登录数据库之后 键入: @/全路径/文件名      即可执行*.sql 文件            例 假设有一个 test.sql 文件 所在路径是/home/oracle/ ...