题解报告:hdu 3549 Flow Problem(最大流入门)

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实现,即每个阶段先进行一次bfs给图分层,然后再在该图上进行1次或多次寻找增广路,时间复杂度大概为O(|E||V|2)。

AC代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int INF=0x3f3f3f3f;
 4 const int maxn=1005;
 5 struct edge{int to,cap,rev;};//指向节点to,边容量是cap,rev是记录为当前邻接点to反向边的编号
 6 vector<edge> G[maxn];//邻接表,G[i][j]表示节点i连接的第j条边包含的所有信息
 7 int t,n,m,x,y,c,level[maxn];//level数组在bfs时为分层图所用
 8 void add_edge(int from,int to,int cap){//向图中增加一条从s到t容量为cap的边
 9     G[from].push_back((edge){to,cap,G[to].size()});
10     G[to].push_back((edge){from,0,G[from].size()-1});
11 }
12 //通过bfs给图分层次
13 void bfs(int s){
14     memset(level,-1,sizeof(level));//刚开始每个节点的层次置为-1
15     queue<int> que;//队列实现bfs
16     level[s]=0;//源点s为第0层
17     que.push(s);
18     while(!que.empty()){//给图分层
19         int v=que.front();que.pop();
20         for(size_t i=0;i<G[v].size();++i){//遍历节点v与之相连的每条边
21             edge &e=G[v][i];//取出与节点v相连的第i条边
22             if(e.cap>0&&level[e.to]<0){//如果边残余流量大于0,且节点e.to还未分层
23                 level[e.to]=level[v]+1;//节点e.to的层次为指向它的节点v所在层次数加1
24                 que.push(e.to);
25             }
26         }
27     }
28 }
29 //通过dfs寻找最短增广路
30 int dfs(int v,int t,int f){//v->t,当前流量是f
31     if(v==t)return f;//如果当前节点v为本身,则直接返回当前的流量值
32     for(size_t i=0;i<G[v].size();++i){//遍历节点v与之相连的每条边
33         edge &e=G[v][i];//取出与节点v相连的第i条边
34         if(e.cap>0 && level[v]<level[e.to]){//如果该边残流量大于0,且邻接点e.to是v的下一级,就增广下去
35             int d=dfs(e.to,t,min(f,e.cap));//维护增广路径上的最小容量:s-->t,最小容量为d
36             if(d>0){//回溯时如果增广路径上的最小容量大于0,说明找到了增广路径,将增广路径上的每条边减去最小可流量
37                 e.cap-=d;//正向边减去最小流量
38                 G[e.to][e.rev].cap+=d;//反向边加上最小流量
39                 return d;//回溯到上一层,返回当前增广路径上的最小容量;当回到源点S时,继续查找是否还有增广路径
40             }
41         }
42     }
43     return 0;//否则说明没有增广路,返回当前的最小的流量为0
44 }
45 //Dinic算法实现最大流,每个阶段执行完一次bfs分层之后,只需查找当前层次图中是否还增广路径即可
46 int max_flow(int s,int t){
47     int flow=0;
48     while(1){
49         bfs(s);//每个阶段先bfs将图分层标记
50         if(level[t]<0)return flow;//如果分层之后,终点t的层次小于0,即没有被分层,说明已没有增广路了,直接返回当前最大流量
51         int f=dfs(s,t,INF);
52         while(f>0){//在该层次图中找到增广路的最小流量
53             flow+=f;//先将其流量相加
54             f=dfs(s,t,INF);//然后循环找该层次图中是否还有增广路径
55         }
56     }
57 }
58 int main(){
59     while(~scanf("%d",&t)){
60         for(int cas=1;cas<=t;++cas){
61             scanf("%d%d",&n,&m);
62             for(int i=0;i<=n;++i)G[i].clear();
63             while(m--){
64                 scanf("%d%d%d",&x,&y,&c);
65                 add_edge(x,y,c);
66             }
67             printf("Case %d: %d\n",cas,max_flow(1,n));
68         }
69     }
70     return 0;
71 }

原文地址:https://www.cnblogs.com/acgoto/p/9845914.html

时间: 2024-11-18 23:32:23

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

hdu 3549 Flow Problem (最大流入门题)

增广路: 1 /************************************************************* 2 题目: Flow Problem(HDU 3549) 3 链接: http://acm.hdu.edu.cn/showproblem.php?pid=3549 4 题意: 给一个单向图,求从1到n的最大流 5 算法: 最大流之增广路(入门) 6 算法思想: 不断用BFS找通路,没每找一条路,记录这条路的最小流, 7 再给这条路上的所有流量减去这个最小值.

网络流 HDU 3549 Flow Problem

网络流 HDU 3549 Flow Problem 题目:http://acm.hdu.edu.cn/showproblem.php?pid=3549 用增广路算法进行求解,注意的问题有两个: 1. 每次增广的时候,反向流量也要进行更行,一开始没注意,WA了几次 ORZ 2. 对于输入的数据,容量要进行累加更新. // 邻接矩阵存储 #include <bits/stdc++.h> using namespace std; const int INF = 0x7fffffff; const i

hdu 3549 Flow Problem (网络最大流)

Flow Problem Time Limit: 5000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 6674    Accepted Submission(s): 3112 Problem Description Network flow is a well-known difficult problem for ACMers. Given a graph, yo

HDU 3549 Flow Problem ( 最大流 -EK 算法)

C++,G++的读取速度差距也太大了 Flow Problem 题意:n,m表示n个点m条有向带权边 问:从1-n最大流多少 裸最大流,拿来练手,挺不错的 #include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <queue> #include <algorithm> const int N = 210; #define

HDU 3549 Flow Problem 网络最大流问题 Edmonds_Karp算法

题目链接:HDU 3549 Flow Problem Flow Problem Time Limit: 5000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 8218    Accepted Submission(s): 3824 Problem Description Network flow is a well-known difficult problem f

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

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3549 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

HDU 3549 Flow Problem (用一道最裸的最大流开启网络流算法之路)

Flow Problem Time Limit: 5000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 9423    Accepted Submission(s): 4405 Problem Description Network flow is a well-known difficult problem for ACMers. Given a graph, y

hdu 3549 Flow Problem

Flow Problem 题意:N个顶点M条边,(2 <= N <= 15, 0 <= M <= 1000)问从1到N的最大流量为多少? 分析:直接使用Edmonds_Karp算法即可:下面是对增广路的一些理解和代码的解释: 残量:容量-流量: 增广:求出从源点到汇点的一条道路中所有残量的最小值d,把对应的所有边上的流量增加d,反向边(t->s)流量减少d(反向边的cap其实一直是0,只是flow为负了); 技巧:这次的ins的标号是从0开始的,即tot++,之前我都是++t

HDU 3549 Flow Problem (最大流ISAP)

Flow Problem Time Limit: 5000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 8199    Accepted Submission(s): 3814 Problem Description Network flow is a well-known difficult problem for ACMers. Given a graph, yo

HDU 3549 Flow Problem(最大流)

Flow Problem Time Limit: 5000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 12625    Accepted Submission(s): 6004 Problem Description Network flow is a well-known difficult problem for ACMers. Given a graph,