http://hihocoder.com/problemset/problem/1369?sid=1108721

别人都说先学网络流再学二分图,但是我先学了二分图的,感觉网络流好高端啊。

首先对于原图,e[u][v],找到一条路径从be --> en后,要更新残余网络。

什么意思,其他东西自己百度。其实就是建反向边。

比如:

1 --> 2   w = 1

1 --> 3   w = 1

2 --> 3   w = 1

2 --> 4   w = 1

3 --> 4   w = 1

那么如果一开始网络流找到的增广路是1-->2-->3-->4后,整个图的最大流就是1,这样就错了。

应该是1-->2-->4和1-->3-->4,最大流是2.所以在2的时候,就要判断它应该流去那里了,如果每种情况都暴力一下, 复杂度是指数级。

但是如果建立反向边后,比如找到了1-->2-->3-->4,

则建立

4-->3  w = 1

3-->2  w = 1

2-->1  w = 1

这样做了的话,就可以继续找增广路,可以找到1-->3-->2-->4,贡献是1,

为什么可以这样呢?其实就是相当于把水流回去2那里,让2重新选。

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
const int maxn = + ;
int e[maxn][maxn];
int pre[maxn], flow[maxn];
int n, m;
int bfs(int be, int en) {
queue<int> que;
memset(pre, false, sizeof pre);
pre[be] = -, flow[be] = inf;
que.push(be);
while (!que.empty()) {
int id = que.front();
que.pop();
if (id == en) break; // 找到增广路径
for (int i = ; i <= n; ++i) {
if (pre[i] == && e[id][i] > ) {
pre[i] = id;
flow[i] = min(flow[id], e[id][i]);
que.push(i);
}
}
}
if (pre[en] == ) return -;
else return flow[en];
}
int maxFlow(int be, int en) {
int sumFlow = ;
while (true) {
int res = bfs(be, en);
if (res == -) break; //找不到增广路
int u = pre[en], v = en;
while (u != -) {
e[u][v] -= res;
e[v][u] += res;
v = u;
u = pre[v];
}
sumFlow += res;
}
return sumFlow;
}
void work() {
scanf("%d%d", &n, &m);
for (int i = ; i <= m; ++i) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
e[u][v] += w;
}
cout << maxFlow(, n) << endl;
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
work();
return ;
}

最新文章

  1. [翻译]开发文档:android Bitmap的高效使用
  2. 各类坐标系相互之间的转换(84互转GC02,GC02互转BD09)
  3. python征程2.0(python基础)
  4. Html5 Egret游戏开发 成语大挑战(四)选关界面
  5. 构建web应用示例
  6. 手机端使用rem适配
  7. centos6.4 无法进入图形界面的问题及解决
  8. Visual Studio无法添加断点
  9. SQL Server Profiler监控SQL Server性能
  10. phantomjs截图的实践
  11. 如何实现 iOS 自定义状态栏
  12. hdc和hwnd的区别
  13. git config
  14. js原生设计模式——4安全的工厂方法模式之Factory方法模式
  15. option触发事件两种方法总结
  16. 08-图8 How Long Does It Take
  17. linux常见故障处理
  18. [物理学与PDEs]第1章习题7 载流线圈的磁场
  19. EM算法(坐标上升算法)
  20. python server

热门文章

  1. struts2的通配符与动态方法调用
  2. L89
  3. (转)linux 打开文件数 too many open files 解决方法
  4. 网络编程学习笔记-MAC地址和IP地址的关系
  5. 设置可见GPU方式
  6. [转]JavaScript的实例化与继承:请停止使用new关键字
  7. DSP编程
  8. UDK性能优化
  9. hdu水仙花
  10. Druid 在spring中的配置