poj 1459 Power Network(Emonds_karp)
看了一下午的最大流,终于还是弄明白了一点,唉,不容易啊~~
许多流问题主要是确定这类系统网络所能承受的最大流量以及如何达到这个最大流量。
这里有必要说到一点,网络流的时间复杂度都是很悲观的,一般情况下绝对没有可能到达那个复杂度的。
最大流的详细讲解及证明:
http://course.cug.edu.cn/cugFirst/operational_research/main/charpter7/p4.htm
网络最大流的Emonds_karp算法:
http://www.cppblog.com/mythit/archive/2009/04/19/80470.html
Edmonds-Karp 通过采用了广度优先的搜索策略得以使其复杂度达到O(V*E^2)。
以及模板题:http://poj.org/problem?id=1273
再说一下这道题,其实这题也是一个到模板题,只是构图比较难,它是让求多个源点到多个汇点的,刚开始没读懂题,看了看解题报告,看到他们都是将所有的发电站看成源点,将所有用户看成汇点,中转站看成普通点,然后构图,将源点和汇点加进去就行了,还有就是字符串的处理也很费劲,除此之外就是套模板了。
想说的是效率问题,第一次是直接套用的上一个模板,用的stl中的队列,加上使用cin输入的,竟然用了1625ms,然后改用自己写的队列,变成了719ms,再然后,将cin改为scanf,就变成了500ms了~~
代码:
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <algorithm> #include <queue> #include <math.h> #define maxx 105 #define INF 0xffffff using namespace std; struct node { int qu[maxx] ; int head ; int tail ; }q ; int map[maxx][maxx] , flow[maxx] , path[maxx] ; int n , m , np , nc , start , end ; int init() { q.head = q.tail = 0; return 1; } int push ( int x ) { q.qu[q.tail] = x ; q.tail++ ; return 1; } int front() { int x = q.qu[q.head] ; q.head++ ; return x ; } int bfs() { //queue<int>q; int i , j , ss , ee , t ; memset( path , -1 , sizeof ( path )); path[start] = 0 ; flow[start] = INF ; init(); push( start ); while ( q.head != q.tail ) { t = front(); if ( t == end )break; for ( i = 1 ; i <= end ; i++ ) if ( i != start && path[i] == -1 && map[t][i] ) { flow[i] = flow[t] < map[t][i] ? flow[t] : map[t][i] ; path[i] = t ; push ( i ); } } if ( path[end] == -1 ) return -1; return flow[end] ; } int Edmonds_karp() { int step = 0 ; int s = 0; while ( (step = bfs ())!= -1) { s += step ; int ex = end ; while ( ex != start ) { int t = path[ex] ; map[t][ex] -= step ; map[ex][t] += step ; ex = t ; } } return s ; } int main() { int x , y , z , i ; char c ; start = 0 ; while ( scanf ( "%d%d%d%d" , &n , &np , &nc , &m ) != EOF ) { memset( map , 0 , sizeof ( map )); for ( i = 1 ; i <= m ; i++ ) { while ( ( c = getchar()) != '(' ); scanf ( "%d" , &x ); getchar(); scanf ( "%d" , &y ); getchar(); scanf ( "%d" , &z ); map[x+1][y+1] = z; } end = n + 1 ; n += 2 ; m += ( nc + np ); for ( i = 1 ; i <= np ; i++ ) { while ( ( c = getchar()) != '('); scanf ( "%d" , &x ); getchar(); scanf ( "%d" , &z ); map[start][x+1] = z ; } for ( i = 1 ; i <= nc ; i++ ) { while ( (c = getchar()) != '(' ); scanf ( "%d" , &x ); getchar(); scanf ( "%d" , &z ); map[x+1][end] = z ; } printf ( "%d\n", Edmonds_karp() ); } return 0; }