1 #include <iostream> 2 #include <queue> 3 using namespace std; 4 int G[300][300]; 5 int Prev[300]; //路径上每个节点的前驱节点 6 bool Visited[300]; 7 int n,m; //m是顶点数目,顶点编号从1开始 1是源,m是汇, n是 边数 8 9 int Augment() 10 { 11 int v; 12 int i; 13 deque<int> q; 14 memset(Prev,0,sizeof(Prev)); 15 memset(Visited,0,sizeof(Visited)); 16 Prev[1] = 0; 17 Visited[1] = 1; 18 q.push_back(1); 19 bool bFindPath = false; 20 //用bfs寻找一条源到汇的可行路径 21 while (!q.empty()) 22 { 23 v = q.front(); 24 q.pop_front(); 25 for (i = 1; i <= m; i++) 26 { 27 if (G[v][i] > 0 && Visited[i] == 0) 28 { 29 //必须是依然有容量的边,才可以走 30 Prev[i] = v; 31 Visited[i] = 1; 32 if( i == m ) 33 { 34 bFindPath = true; 35 q.clear(); 36 break; 37 } 38 else 39 q.push_back(i); 40 } 41 } 42 } 43 44 if (!bFindPath) 45 return 0; 46 int nMinFlow = 999999999; 47 v = m; //寻找源到汇路径上容量最小的边,其容量就是此次增 加的总流量 48 while( Prev[v] ) 49 { 50 nMinFlow = min( nMinFlow,G[Prev[v]][v]); 51 v = Prev[v]; 52 } 53 //沿此路径添加反向边,同时修改路径上每条边的容量 54 v = m; 55 while( Prev[v] ) 56 { 57 G[Prev[v]][v] -= nMinFlow; 58 G[v][Prev[v]] += nMinFlow; 59 v = Prev[v]; 60 } 61 return nMinFlow; 62 } 63 64 int main() 65 { 66 while (cin >> n >> m) 67 { 68 //m是顶点数目,顶点编号从1开始 69 int i,j,k; 70 int s,e,c; 71 memset( G,0,sizeof(G)); 72 for( i = 0;i < n;i ++ ) 73 { 74 cin >> s >> e >> c; 75 G[s][e] += c; //两点之间可能有多条边 76 } 77 int MaxFlow = 0; 78 int aug; 79 while( aug = Augment() ) 80 MaxFlow += aug; 81 cout << MaxFlow << endl; 82 } 83 return 0; 84 }
时间: 2024-10-06 08:51:38