HDU 3549 Flow Problem(最大流)
Time Limit: 5000/5000 MS (Java/Others)
Memory Limit: 65536/32768 K (Java/Others)
【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. |
网络流是ACMers众所周知的一个难题。给定一幅图,你的任务是找出这个加权有向图的最大流。 |
【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) |
输入的第一行是一个整数T,表示测试用例的数量。 对于每个测试用例,第一行有两个整数N和M,表示图中顶点与边的数量。(2 <= N <= 15, 0 <= M <= 1000)接着M行,每行三个整数X,Y和C,有一条从X到Y的边,其容量为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. |
对于每个测试样例,输出从源点1到汇点N的最大流。 |
【Sample Input - 输入样例】 |
【Sample Output - 输出样例】 |
2 3 2 1 2 1 2 3 1 3 3 1 2 1 2 3 1 1 3 1 |
Case 1: 1 Case 2: 2 |
【题解】
最大流问题
题目描述得太简单,自己从来没做过,就去百度了一下大概的规则
然后……就当成水管来看吧…………
比较简单的方式的用DFS实现,注意处理好搜索与回溯即可。
搜索时可以每次只找一条1→N的路径,也可以在当前已走过的路径下尽可能地推送流量到N,即多条路径(不过这种方式比较费时,因为会在重复尝试一些无效的路径)
为了方便回溯,每次A→B推送的流量等于添加B→A的容量。
vector的查询速度并不是很快,多次使用的时候用指针或是继承可以提高速度,以及看/写起来舒服点……
【代码 C++】
1 #include<cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <vector> 5 int n; 6 struct edge{ 7 int next, capacity, last_i; 8 }; 9 std::vector<edge> data[16]; 10 bool us[16]; 11 void read(){ 12 int m, x, y, c, i, j, map[16][16]; 13 memset(map, 0, sizeof(map)); 14 scanf("%d%d", &n, &m); 15 for (i = 1; i <= n; ++i) data[i].clear(); 16 for (i = 0; i < m; ++i) scanf("%d%d%d", &x, &y, &c), map[x][y] += c; 17 edge temp = { 0, 0, 0 }; 18 for (i = 1; i < n; ++i){ 19 for (j = i + 1; j <= n; ++j){ 20 if (map[i][j] + map[j][i] == 0) continue; 21 temp.next = j; temp.capacity = map[i][j]; temp.last_i = data[j].size(); 22 data[i].push_back(temp); 23 temp.next = i; temp.capacity = map[j][i]; temp.last_i = data[i].size() - 1; 24 data[j].push_back(temp); 25 } 26 } 27 } 28 int send(int nowEdge, int flowWait){ 29 if (nowEdge == n) return flowWait; 30 us[nowEdge] = 1; 31 int hadSend, temp, i, ed = data[nowEdge].size(); 32 for (i = hadSend = 0; i < ed; ++i){ 33 edge &now = data[nowEdge][i]; 34 if (!us[now.next] && now.capacity){ 35 temp = send(now.next, std::min(now.capacity, flowWait - hadSend)); 36 if (temp){ 37 hadSend += temp; now.capacity -= temp; 38 data[now.next][now.last_i].capacity += temp; 39 } 40 } 41 } 42 return hadSend; 43 } 44 int main(){ 45 int t, i, opt, temp; 46 for (i = scanf("%d", &t); i <= t; ++i){ 47 printf("Case %d: ", i); 48 read(); 49 for (opt = 0; memset(us, 0, sizeof(us));){ 50 temp = send(1, 15000); 51 if (temp) opt += temp; 52 else break; 53 } 54 printf("%d ", opt); 55 } 56 return 0; 57 }