HDU4289Control(最大流)
看了这道题,然后重新开始练习自己的刚敲不久的网络流,发现还是难以一遍敲得完整啊,,,,,
调了。。。遍,改了。。。遍,测了。。。遍,交了,,,遍,总算是A了,,不简单啊
然后试着用了其他两种算法EK和dinic都试着去练习一下,慢慢A了,,,真是不简单有木有
题目大意是这样的,有一些小偷打算从城市S到城市T,但是我们不知道他们会走哪些边,为了确保一定可以能够抓住所有的小偷,现在需要在某些城市布置一些警察,已知在城市i布置的花费是P[i],现在要使的抓住小偷的同时我的花费最小,求最小花费。
这里用到了最大流的一个定理,最小割最大流定理:当起点到终点的最大流算出来时,这个最大流就是将图划分为两个互不连通的集合的最小割。证明可以自己百度或看其他神牛的博客。
有了这个定理,就变成了裸的最大流问题了
下面我试着用三种方法做了这道题,比较了一下发现最快的依然是SAP,其次是dinic,最后是EK算法
SAP
- #include <map>
- #include <set>
- #include <stack>
- #include <queue>
- #include <cmath>
- #include <ctime>
- #include <vector>
- #include <cstdio>
- #include <cctype>
- #include <cstring>
- #include <cstdlib>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- #define INF 0x3f3f3f3f
- #define inf ((LL)1<<40)
- #define lson k<<1, L, mid
- #define rson k<<1|1, mid+1, R
- #define mem0(a) memset(a,0,sizeof(a))
- #define mem1(a) memset(a,-1,sizeof(a))
- #define mem(a, b) memset(a, b, sizeof(a))
- #define FOPENIN(IN) freopen(IN, "r", stdin)
- #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
- template<class T> T ABS ( T a) { return a >= ? a : -a; }
- template<class T> T CMP_MIN ( T a, T b ) { return a < b; }
- template<class T> T CMP_MAX ( T a, T b ) { return a > b; }
- template<class T> T MAX ( T a, T b ) { return a > b ? a : b; }
- template<class T> T MIN ( T a, T b ) { return a < b ? a : b; }
- template<class T> T GCD ( T a, T b ) { return b ? GCD ( b, a % b ) : a; }
- template<class T> T LCM ( T a, T b ) { return a / GCD ( a, b ) * b; }
- template<class T> void SWAP( T& a, T& b ) { T t = a; a = b; b = t; }
- typedef __int64 LL;
- //typedef long long LL;
- const int MAXN = ;
- const int MAXM = ;
- const double eps = 1e-;
- const double PI = 4.0 * atan(1.0);
- const LL MOD = ;
- #define L(i) (i<<1)
- #define R(i) (i<<1|1)
- int m, n, s, d;
- struct Edge { int to, cap, next; }edge[MAXM<<];
- int tot, head[MAXN];
- int src, des;
- int gap[MAXN], dep[MAXN], aug[MAXN], cur[MAXN], pre[MAXN];
- void addEdge(int u, int v, int c)
- {
- edge[tot].to = v; edge[tot].cap = c; edge[tot].next = head[u];
- head[u] = tot ++;
- edge[tot].to = u; edge[tot].cap = ; edge[tot].next = head[v];
- head[v] = tot ++;
- }
- void init()
- {
- int x, y;
- tot = ;
- mem1(head); mem0(edge);
- scanf("%d %d", &s, &d);
- for(int i = ; i <= n; i ++)
- {
- scanf("%d", &x);
- addEdge(L(i), R(i), x);
- addEdge(R(i), L(i), x);
- }
- for(int i = ; i < m; i ++)
- {
- scanf("%d %d", &x, &y);
- addEdge(R(x), L(y), INF);
- addEdge(R(y), L(x), INF);
- }
- src = ;
- des = (n+)<<;
- addEdge(src, L(s), INF);
- addEdge(R(d), des, INF);
- }
- int SAP(int n)
- {
- mem0(gap);
- mem0(dep);
- mem0(aug);
- mem0(pre);
- aug[src] = INF;
- pre[src] = -;
- gap[] = n;
- int max_flow = , u = src;
- for(int i = ; i <= n; i ++)
- cur[i] = head[i];
- while(dep[src] < n)
- {
- if(u == des)
- {
- max_flow += aug[des];
- for(int v = pre[des]; v != -; v = pre[v])
- {
- int id = cur[v];
- edge[id].cap -= aug[des];
- edge[id^].cap += aug[des];
- aug[v] -= aug[des];
- if(edge[id].cap == )
- u = v;
- }
- }
- int flag = ;
- for(int i = cur[u]; i != -; i = edge[i].next)
- {
- int v = edge[i].to;
- if(edge[i].cap > && dep[u] == dep[v]+)
- {
- flag = ;
- pre[v]= u;
- cur[u] = i;
- aug[v] = MIN(aug[u], edge[i].cap);
- u = v;
- break;
- }
- }
- if(!flag)
- {
- if(--gap[dep[u]] == )
- break;
- int min_dep = n;
- cur[u] = head[u];
- for(int i = head[u]; i != -; i = edge[i].next)
- {
- int v = edge[i].to;
- if(edge[i].cap > && dep[v] < min_dep)
- {
- min_dep = dep[v];
- cur[u] = i;
- }
- }
- dep[u] = min_dep + ;
- gap[dep[u]] ++;
- if(pre[u] != -) u = pre[u];
- }
- }
- return max_flow;
- }
- int main()
- {
- while(~scanf("%d %d", &n, &m))
- {
- init();
- printf("%d\n", SAP(des));
- }
- return ;
- }
dinic
- #include <map>
- #include <set>
- #include <stack>
- #include <queue>
- #include <cmath>
- #include <ctime>
- #include <vector>
- #include <cstdio>
- #include <cctype>
- #include <cstring>
- #include <cstdlib>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- #define INF 0x3f3f3f3f
- #define inf ((LL)1<<40)
- #define lson k<<1, L, mid
- #define rson k<<1|1, mid+1, R
- #define mem0(a) memset(a,0,sizeof(a))
- #define mem1(a) memset(a,-1,sizeof(a))
- #define mem(a, b) memset(a, b, sizeof(a))
- #define FOPENIN(IN) freopen(IN, "r", stdin)
- #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
- template<class T> T ABS ( T a) { return a >= ? a : -a; }
- template<class T> T CMP_MIN ( T a, T b ) { return a < b; }
- template<class T> T CMP_MAX ( T a, T b ) { return a > b; }
- template<class T> T MAX ( T a, T b ) { return a > b ? a : b; }
- template<class T> T MIN ( T a, T b ) { return a < b ? a : b; }
- template<class T> T GCD ( T a, T b ) { return b ? GCD ( b, a % b ) : a; }
- template<class T> T LCM ( T a, T b ) { return a / GCD ( a, b ) * b; }
- template<class T> void SWAP( T& a, T& b ) { T t = a; a = b; b = t; }
- typedef __int64 LL;
- //typedef long long LL;
- const int MAXN = ;
- const int MAXM = ;
- const double eps = 1e-;
- const double PI = 4.0 * atan(1.0);
- const LL MOD = ;
- #define L(i) (i<<1)
- #define R(i) (i<<1|1)
- int m, n, s, d;
- struct Edge { int to, cap, next; }edge[MAXM<<];
- int tot, head[MAXN];
- int src, des;
- int dis[MAXN];
- void addEdge(int u, int v, int c)
- {
- edge[tot].to = v; edge[tot].cap = c; edge[tot].next = head[u];
- head[u] = tot ++;
- edge[tot].to = u; edge[tot].cap = ; edge[tot].next = head[v];
- head[v] = tot ++;
- }
- void init()
- {
- int x, y;
- tot = ;
- mem1(head); mem0(edge);
- scanf("%d %d", &s, &d);
- for(int i = ; i <= n; i ++)
- {
- scanf("%d", &x);
- addEdge(L(i), R(i), x);
- addEdge(R(i), L(i), x);
- }
- for(int i = ; i < m; i ++)
- {
- scanf("%d %d", &x, &y);
- addEdge(R(x), L(y), INF);
- addEdge(R(y), L(x), INF);
- }
- src = ;
- des = (n+)<<;
- addEdge(src, L(s), INF);
- addEdge(R(d), des, INF);
- }
- bool bfs()
- {
- queue<int>q;
- mem1(dis);
- dis[src] = ;
- q.push(src);
- while(!q.empty())
- {
- int u = q.front(); q.pop();
- for(int i = head[u]; i != -; i = edge[i].next)
- {
- int v = edge[i].to;
- if(dis[v] == - && edge[i].cap > )
- {
- dis[v] = dis[u] + ;
- q.push(v);
- }
- }
- }
- return dis[des] != -;
- }
- int dfs(int cur, int aug)
- {
- if(cur == des || aug == )
- return aug;
- int flow = ;
- for(int i = head[cur]; i != -; i = edge[i].next)
- {
- int v = edge[i].to;
- if ( dis[v] == dis[cur]+ && edge[i].cap > )
- {
- int f = dfs( v, MIN(edge[i].cap, aug) );
- edge[i].cap -= f;
- edge[i^].cap += f;
- flow += f;
- aug -= f;
- if(aug == )
- break;
- }
- }
- return flow;
- }
- int dinic()
- {
- int res = ;
- while (bfs())
- {
- res += dfs(src, INF);
- }
- return res;
- }
- int main()
- {
- //FOPENIN("in.txt");
- while(~scanf("%d %d", &n, &m))
- {
- init();
- printf("%d\n", dinic());
- }
- return ;
- }
EK
- #include <map>
- #include <set>
- #include <stack>
- #include <queue>
- #include <cmath>
- #include <ctime>
- #include <vector>
- #include <cstdio>
- #include <cctype>
- #include <cstring>
- #include <cstdlib>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- #define INF 0x3f3f3f3f
- #define inf ((LL)1<<40)
- #define lson k<<1, L, mid
- #define rson k<<1|1, mid+1, R
- #define mem0(a) memset(a,0,sizeof(a))
- #define mem1(a) memset(a,-1,sizeof(a))
- #define mem(a, b) memset(a, b, sizeof(a))
- #define FOPENIN(IN) freopen(IN, "r", stdin)
- #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
- template<class T> T ABS ( T a) { return a >= ? a : -a; }
- template<class T> T CMP_MIN ( T a, T b ) { return a < b; }
- template<class T> T CMP_MAX ( T a, T b ) { return a > b; }
- template<class T> T MAX ( T a, T b ) { return a > b ? a : b; }
- template<class T> T MIN ( T a, T b ) { return a < b ? a : b; }
- template<class T> T GCD ( T a, T b ) { return b ? GCD ( b, a % b ) : a; }
- template<class T> T LCM ( T a, T b ) { return a / GCD ( a, b ) * b; }
- template<class T> void SWAP( T& a, T& b ) { T t = a; a = b; b = t; }
- typedef __int64 LL;
- //typedef long long LL;
- const int MAXN = ;
- const int MAXM = ;
- const double eps = 1e-;
- const double PI = 4.0 * atan(1.0);
- const LL MOD = ;
- #define L(i) (i<<1)
- #define R(i) (i<<1|1)
- int n, m, s, d;
- int src, des;
- int cap[MAXN][MAXN], flow[MAXN][MAXN], pre[MAXN], a[MAXN];
- void init()
- {
- int x, y;
- src = ;
- des = (n+)<<;
- mem0(cap);mem0(pre);
- scanf("%d %d", &s, &d);
- cap[src][L(s)] = INF;
- cap[R(d)][des] = INF;
- for(int i = ; i <= n; i ++)
- {
- scanf("%d", &x);
- cap[L(i)][R(i)] = x;
- cap[R(i)][L(i)] = x;
- }
- for(int i = ; i < m; i ++)
- {
- scanf("%d %d", &x, &y);
- cap[R(x)][L(y)] = INF;
- cap[R(y)][L(x)] = INF;
- }
- }
- int EK(int n)
- {
- queue<int>q;
- mem0(flow);
- int max_flow = ;
- while(true)
- {
- mem0(a);
- a[src] = INF;
- q.push(src);
- while(!q.empty())
- {
- int u = q.front(); q.pop();
- for(int v = ; v <= n; v ++) if(!a[v] && cap[u][v]>flow[u][v])
- {
- pre[v]= u;
- q.push(v);
- a[v] = MIN(a[u], cap[u][v] - flow[u][v]);
- }
- }
- if(a[des] == ) break;
- for(int u = des; u != src; u = pre[u])
- {
- flow[pre[u]][u] += a[des];
- flow[u][pre[u]] -= a[des];
- }
- max_flow += a[des];
- }
- return max_flow;
- }
- int main()
- {
- //FOPENIN("in.txt");
- while(~scanf("%d %d", &n, &m))
- {
- init();
- printf("%d\n", EK(des));
- }
- return ;
- }
HDU4289Control(最大流)的更多相关文章
- HDU4289Control 无向图拆点最大流
/* ** 无向图拆点,求最大流,最大流即为割点个数. */ #include <iostream> #include <cstdio> #include <cstrin ...
- 使用C#处理基于比特流的数据
使用C#处理基于比特流的数据 0x00 起因 最近需要处理一些基于比特流的数据,计算机处理数据一般都是以byte(8bit)为单位的,使用BinaryReader读取的数据也是如此,即使读取bool型 ...
- HTML 事件(三) 事件流与事件委托
本篇主要介绍HTML DOM中的事件流和事件委托. 其他事件文章 1. HTML 事件(一) 事件的介绍 2. HTML 事件(二) 事件的注册与注销 3. HTML 事件(三) 事件流与事件委托 4 ...
- FILE文件流的中fopen、fread、fseek、fclose的使用
FILE文件流用于对文件的快速操作,主要的操作函数有fopen.fseek.fread.fclose,在对文件结构比较清楚时使用这几个函数会比较快捷的得到文件中具体位置的数据,提取对我们有用的信息,满 ...
- java.IO输入输出流:过滤流:buffer流和data流
java.io使用了适配器模式装饰模式等设计模式来解决字符流的套接和输入输出问题. 字节流只能一次处理一个字节,为了更方便的操作数据,便加入了套接流. 问题引入:缓冲流为什么比普通的文件字节流效率高? ...
- java 字节流与字符流的区别
字节流与和字符流的使用非常相似,两者除了操作代码上的不同之外,是否还有其他的不同呢?实际上字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作的,而字符流在操作时使用了缓冲区,通过缓冲区再操作 ...
- BZOJ 3504: [Cqoi2014]危桥 [最大流]
3504: [Cqoi2014]危桥 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1407 Solved: 703[Submit][Status] ...
- java I/O流
输入流(读取数据的流) BufferedInputStream---继承--->FileInputStream--继承--->InputStream------> (1)字节流操作中 ...
- Ford-Fulkerson 最大流算法
流网络(Flow Networks)指的是一个有向图 G = (V, E),其中每条边 (u, v) ∈ E 均有一非负容量 c(u, v) ≥ 0.如果 (u, v) ∉ E 则可以规定 c(u, ...
随机推荐
- Swustoj题目征集计划
SWUST OJ题目征集计划 鉴于SWUST OJ长时间没有新题添加,题目数量和类型有限,同时也为加强同学们之间的算法交流,享受互相出题AC的乐趣,提高算法水平,现在启动题目征集计划啦~ 当你遇到 ...
- wxWidgets简单的多线程
#include <wx/wx.h> #include <wx/thread.h> #include <wx/event.h> #include <wx/pr ...
- (转)每天一个Linux命令(4): mkdir
http://www.cnblogs.com/peida/archive/2012/10/25/2738271.html linux mkdir 命令用来创建指定的名称的目录,要求创建目录的用户在当前 ...
- 每天一个Linux命令(3): cd
Linux cd 命令可以说是Linux中最基本的命令语句,其他的命令语句要进行操作,都是建立在使用 cd 命令上的. 所以,学习Linux 常用命令,首先就要学好 cd 命令的使用方法技巧. 1. ...
- 手动编译Spring4.2源码,以及把源码导入myEclipse中
前提条件,先在本地配置好JDK1.8, 安装好Git 执行下面命令: 1,双击Git Bash, 进入源码存放路径 cd E:\Foler 2,git clone git@github.com:spr ...
- Shell教程5-Shell运算符
Bash 支持很多运算符,包括算数运算符.关系运算符.布尔运算符.字符串运算符和文件测试运算符. 原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最 ...
- Android NDK OpenCV C++
NDK中的OpenCV http://blog.csdn.net/yanzi1225627/article/details/8525720
- php 实现 jsonp 数据接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...
- 分段统计与Oracle的分析函数、逻辑判断等知识点的综合运用
重点部分:TOTAL层 项目要求: 统计每个巡检员(USER_ID)当前月的签到率及查询相关字段 签到率公式:以巡检员为单位, (当月至今天为止签到的所有点/该月巡检点的总个数)=(b.Point/a ...
- 2015-10-27 js
1.声明变量: 2.prompt属性的使用: prompt("提示框的标题","提示框的输入提示内容"); prompt的调用结果就是他输入框内的内容!!! 3 ...