poj-1273
来源:互联网 发布:php 明天时间戳 编辑:程序博客网 时间:2024/05/16 07:41
// 936K 32MS G++#include <cstdio>#include <cstring>#include <queue>#define MAX 210#define INF 999999long long intersectionMap[MAX][MAX];int prev[MAX];int flow[MAX];int N;int M; // intersection numusing namespace std;queue<int> BFSQueue;long long minFlow;char BFSFlag[MAX];char BFS() { // printf("BFS\n"); memset(prev, 0, sizeof(prev)); memset(flow, 0, sizeof(flow)); memset(BFSFlag, 0, sizeof(BFSFlag)); while(BFSQueue.size()) { BFSQueue.pop(); } BFSQueue.push(1); // from s prev[1] = 0; // s's prev is 0 which means invalid flow[1] = INF; BFSFlag[1] = 1; minFlow = INF; // record the min flow on this argmenting path while(BFSQueue.size()) { int curNodeId = BFSQueue.front(); BFSQueue.pop(); for (int i = 1; i <= M; i++) { // check the adjacney Node if (intersectionMap[curNodeId][i]) { // if has flow > 0 if (!BFSFlag[i]) { BFSFlag[i] = 1; if (!prev[i]) { // if has not visited prev[i] = curNodeId; minFlow = minFlow < intersectionMap[curNodeId][i] ? minFlow : intersectionMap[curNodeId][i]; if (i == M) { // if reach t, a path has been found return 1; } BFSQueue.push(i); } } } } } return 0;}int solve() { long long maxRate = 0; while (BFS()) { // find a augmenting path int prevNodeId = prev[M]; int currentNodeId = M; // check from t to s while(prevNodeId) { // adjust the flow of this path intersectionMap[prevNodeId][currentNodeId] -= minFlow; intersectionMap[currentNodeId][prevNodeId] += minFlow; currentNodeId = prevNodeId; prevNodeId = prev[currentNodeId]; } maxRate += minFlow; } // for (int i = 1; i <= M; i++) { // maxRate += intersectionMap[M][i]; // } printf("%lld\n", maxRate);}int main() { while(scanf("%d %d", &N, &M) != EOF) { int beginIntersection; int endInteresction; long long maxRate; memset(intersectionMap, 0, sizeof(intersectionMap)); for (int i = 0; i < N; i++) { scanf("%d %d %lld", &beginIntersection, &endInteresction, &maxRate); // intersectionMap[beginIntersection][endInteresction] = // intersectionMap[beginIntersection][endInteresction] > maxRate ? // intersectionMap[beginIntersection][endInteresction]: maxRate; intersectionMap[beginIntersection][endInteresction] += maxRate; } solve(); }}
第一道流的题,本来根本不准备涉及流这一块的,因为不但工作中用不到,在现在的面试笔试中也基本没有,从功利性角度出发,
完全没有必要,但是随着最近的刷题,不断的延伸,发现这一块还是避免不了,虽然可能没有什么直接作用,但是没准会有潜移默化的好处。
正好现在也基本能看懂了,就坐坐这些题吧。
这一道应该是流的基本题了,转化难度为0,完全是为了流而流的题,作用就是熟悉和练习Edmonds-Karp算法。
总结一下流程:
算法思路简单,就是用BFS不断的寻找从s到t的增广路,如果找到一条,就对相应的正/反向路径 -/+本次的最大流,
一直到找不到增广路为止,这时候,从s到t的就是最大流。
每次BFS都是从s开始,
在BFS的过程中,有两个额外的关键变量:
一个是本次找到的增广路的所有路径里最小的正向flow值 minFlow,初始为INF。
另外一个是prev数组,来保存此增广路中的每个节点的前驱节点,其实prev[s]在开始置为0,表示没有前驱节点了。
然后在每次BFS检查点curId的周围正向flow大于0(正向flow>0保证了此路是增广路,还可以传输flow)的点集时,除了检查是否BFS过以外,还要检查该点k在不在已经遍历过的路中(及其前驱prev[k]还没有被设置),不在才将此节点k加入到路径中去,如果k是终点t的话,直接返回1表示有增广路存在,如果不是,那么将新加入的这段路的正向flow
和minFlow比较,minFlow取两者最小的。
在找到了一条增广路以后,就根据前驱prev从t反向到s处理每一段路径的正向flow(-minFlow)和反向flow(+minFlow),同时最大流 S(初始为0)+= minFlow.
最后输出minFlow即可。
要注意本题似乎会有重边,eg:
1 2 5
1 2 7
1 2 8
总共3个,都是从1到2的flow,在处理时,要累加起来,等价于最后的 1 2 20.
反向flow存在意义还要研究研究.
- POJ 1273
- poj 1273
- poj 1273
- POJ 1273
- poj 1273
- POJ 1273
- poj 1273
- POJ 1273
- POJ-1273
- poj-1273
- poj 1273
- poj 1273
- poj 1273
- POJ 1273
- poj 1273
- POJ 1273 Drainage Ditches
- POJ 1273 Drainage Ditches
- POJ 1273 Drainage Ditches
- UVA 11427 - Expect the Expected(概率递推期望)
- 使用View.getWidth()方法出现的问题及解决方法
- Linux磁盘挂载操作手册
- 【程序员编程艺术】学习记录2:左旋转字符串之循环移位法
- 【转】在sublime text2中直接编译java文件
- poj-1273
- Anton and Letters - CF#253 (Div. 2)A (443A) 大水
- LCD驱动调试常见问题总结
- Python学习笔记(二):循环
- The resource is not on the build path of a java project
- HTML中的表单
- Kolya and Tandem Repeat - CF#253 (Div. 2)B (443B) 哈希或水题
- 解决Toast重复弹出,Toast单例模式
- poj 1198 二维树状数组