-
Notifications
You must be signed in to change notification settings - Fork 0
/
POJ-1273-Dinic.cpp
136 lines (135 loc) · 2.37 KB
/
POJ-1273-Dinic.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/**
*POJ-1273-Drainage Ditches
*xuchen
*2015-12-19 13:59:05
**/
/**
*Flow network
*Dinic
**/
#include "stdio.h"
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <fstream>
#include "time.h"
using namespace std;
const int INFINITE = 0x3f3f3f3f;
int G[300][300];
bool Visited[300];
int Layer[300];
int n,m; //1是源点,m是汇点
bool CountLayer()
{
int layer = 0;
deque<int>q;
memset(Layer,0xff,sizeof(Layer));//都初始化成-1
Layer[1] = 0;
q.push_back(1);
while( ! q.empty())
{
int v = q.front();
q.pop_front();
for( int j = 1; j <= m; j ++ )
{
if( G[v][j] > 0 && Layer[j] == -1 )
{
//Layer[j] == -1 说明j还没有访问过
Layer[j] = Layer[v] + 1;
if( j == m ) //分层到汇点即可
return true;
else
q.push_back(j);
}
}
}
return false;
}
int Dinic()
{
int i;
int s;
int nMaxFlow = 0;
deque<int> q;//DFS用的栈
while( CountLayer() ) //只要能分层
{
q.push_back(1); //源点入栈
memset(Visited,0,sizeof(Visited));
Visited[1] = 1;
while( !q.empty())
{
int nd = q.back();
if( nd == m ) // nd是汇点
{
//在栈中找容量最小边
int nMinC = INFINITE;
int nMinC_vs; //容量最小边的起点
for( i = 1; i < q.size(); i ++ )
{
int vs = q[i-1];
int ve = q[i];
if( G[vs][ve] > 0 )
{
if( nMinC > G[vs][ve] )
{
nMinC = G[vs][ve];
nMinC_vs = vs;
}
}
}
//增广,改图
nMaxFlow += nMinC;
for( i = 1; i < q.size(); i ++ )
{
int vs = q[i-1];
int ve = q[i];
G[vs][ve] -= nMinC; //修改边容量
G[ve][vs] += nMinC; //添加反向边
}
//退栈到 nMinC_vs成为栈顶,以便继续dfs
while( !q.empty() && q.back() != nMinC_vs )
{
Visited[q.back()] = 0; //没有这个应该也对
q.pop_back();
}
}
else //nd不是汇点
{
for( i = 1; i <= m; i ++ )
{
if( G[nd][i] > 0 && Layer[i] == Layer[nd] + 1 &&
! Visited[i])
{
//只往下一层的没有走过的节点走
Visited[i] = 1;
q.push_back(i);
break;
}
}
if( i > m) //找不到下一个点
q.pop_back(); //回溯
}
}
}
return nMaxFlow;
}
int main()
{
while (cin >> n >> m )
{
int i,j,k;
int s,e,c;
memset( G,0,sizeof(G));
for( i = 0; i < n; i ++ )
{
cin >> s >> e >> c;
G[s][e] += c; //两点之间可能有多条边
}
cout << Dinic() << endl;
}
return 0;
}