一直对最小割模型的理解不够深刻,这段时间学习、总结了一下。
【强烈推荐胡伯涛和彭天翼的论文】
总结几点:
(1)跑完一遍S-T最大流后,在最小割[S,T]中的边必定都是满流的边,但满流的边不一定都是最小割中的边。
(2)最小割的任意方案:跑一遍S-T最大流,然后在残余网络中S能够达到的点为一个割集,剩下的点为另一个割集。
(3)最小割方案的唯一性:跑一遍S-T最大流,如果在残余网络中任意一个点都能从S或者T出发达到,那么最小割方案有唯一性;否则没有唯一性。
(4)跑一遍S-T最大流后,残余网络中所有S能够达到的点必定在S割集中;残余网络中所有T能够达到的点必定在T割集中。
(5)跑一遍S-T最大流后。满足:
若边(u,v)满流,且删掉该边后在残余网络中找不到u到v的路径,则(u,v)可能出现在某个最小割方案中。
若边(u,v)满流,且在残余网络中s能够达到u,v能够达到t,则(u,v)必定出现在任意一个最小割方案中。
例题:
BZOJ 1797 [Ahoi2009]Mincut 最小割
这道题就是上面第(5)点的一个直接应用。那么如何判断某条边是否满足那两个条件呢?
跑完最大流后,在残余网络中求一遍强连通分量。对于某条满流的边(u,v),若u和v不在同一个强连通分量中,则满足第一个条件。若u和S在同一个强连通分量中且v和T在同一个强连通分量中,则满足第二个条件。
1 #include <stack> 2 #include <queue> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 7 using namespace std; 8 9 const size_t Max_N(4050); 10 const size_t Max_M(120050); 11 const int INF(0X7F7F7F7F); 12 13 size_t N; 14 size_t S, T; 15 16 unsigned int Total; 17 unsigned int Head[Max_N]; 18 unsigned int From[Max_M], To[Max_M], Next[Max_M]; 19 int Cap[Max_M], Flow[Max_M]; 20 21 stack<size_t> SV; 22 unsigned int DFS_Clock; 23 unsigned int Pre[Max_N], Low_Link[Max_N]; 24 unsigned int SCC_Total; 25 unsigned int SCC_Number[Max_N]; 26 27 void Get_Val(unsigned int &ret) 28 { 29 ret = 0; 30 char ch; 31 while ((ch = getchar()), (ch > ‘9‘ || ch < ‘0‘)) 32 ; 33 do 34 { 35 (ret *= 10) += ch - ‘0‘; 36 } 37 while ((ch = getchar()), (ch >= ‘0‘ && ch <= ‘9‘)); 38 } 39 40 void Get_Val(int &ret) 41 { 42 ret = 0; 43 char ch; 44 while ((ch = getchar()), (ch > ‘9‘ || ch < ‘0‘)) 45 ; 46 do 47 { 48 (ret *= 10) += ch - ‘0‘; 49 } 50 while ((ch = getchar()), (ch >= ‘0‘ && ch <= ‘9‘)); 51 } 52 53 inline 54 void Add_Edge(const size_t &tot, const size_t &s, const size_t &t, const int &c) 55 { 56 From[tot] = s, To[tot] = t; 57 Cap[tot] = c, Flow[tot] = 0; 58 Next[tot] = Head[s], Head[s] = tot; 59 } 60 61 void init() 62 { 63 unsigned int M; 64 size_t u, v; 65 int c; 66 67 Get_Val(N), Get_Val(M); 68 Get_Val(S), Get_Val(T); 69 while (M--) 70 { 71 Get_Val(u), Get_Val(v), Get_Val(c); 72 Total += 2; 73 Add_Edge(Total, u, v, c); 74 Add_Edge(Total ^ 1, v, u, 0); 75 } 76 } 77 78 size_t Cur[Max_N]; 79 unsigned int Dist[Max_N]; 80 bool BFS() 81 { 82 memset(Dist, 0, sizeof(Dist)); 83 queue<size_t> Q; 84 Q.push(S); 85 Dist[S] = 1; 86 size_t Top; 87 88 while (Q.size()) 89 { 90 Top = Q.front(); 91 Q.pop(); 92 for (size_t i = Head[Top];i;i = Next[i]) 93 if (!Dist[To[i]] && Cap[i] > Flow[i]) 94 { 95 Dist[To[i]] = Dist[Top] + 1; 96 Q.push(To[i]); 97 } 98 } 99 100 return Dist[T]; 101 } 102 103 int DFS(const size_t &u, int a) 104 { 105 if (u == T || a == 0) 106 return a; 107 int Ans(0), f; 108 for (size_t &i = Cur[u];i;i = Next[i]) 109 if (Dist[To[i]] == Dist[u] + 1) 110 if ((f = DFS(To[i], min(a, Cap[i] - Flow[i]))) > 0) 111 { 112 Ans += f; 113 a -= f; 114 Flow[i] += f; 115 Flow[i ^ 1] -= f; 116 if (a == 0) 117 break; 118 } 119 return Ans; 120 } 121 122 void Dinic() 123 { 124 while (BFS()) 125 { 126 for (size_t i = 1;i <= N;++i) 127 Cur[i] = Head[i]; 128 DFS(S, INF); 129 } 130 } 131 132 void Tarjan(const size_t &u) 133 { 134 Pre[u] = Low_Link[u] = ++DFS_Clock; 135 SV.push(u); 136 137 size_t v; 138 for (size_t i = Head[u];i;i = Next[i]) 139 if (Cap[i] > Flow[i]) 140 { 141 v = To[i]; 142 if (!Pre[v]) 143 { 144 Tarjan(v); 145 Low_Link[u] = min(Low_Link[u], Low_Link[v]); 146 } 147 else 148 if (!SCC_Number[v]) 149 Low_Link[u] = min(Low_Link[u], Pre[v]); 150 } 151 152 if (Pre[u] == Low_Link[u]) 153 { 154 ++SCC_Total; 155 while (true) 156 { 157 v = SV.top(); 158 SV.pop(); 159 SCC_Number[v] = SCC_Total; 160 if (u == v) 161 break; 162 } 163 } 164 } 165 166 int main() 167 { 168 init(); 169 170 Dinic(); 171 172 for (size_t i = 1;i <= N;++i) 173 if (!Pre[i]) 174 Tarjan(i); 175 176 for (size_t i = 2;To[i];i += 2) 177 { 178 unsigned int u = From[i], v = To[i]; 179 if (Cap[i] == Flow[i] && SCC_Number[u] != SCC_Number[v]) 180 printf("1 "); 181 else 182 printf("0 "); 183 if (Cap[i] == Flow[i] && SCC_Number[u] == SCC_Number[S] && SCC_Number[v] == SCC_Number[T]) 184 printf("1"); 185 else 186 printf("0"); 187 if (To[i + 2]) 188 printf("\n"); 189 } 190 191 return 0; 192 }
BZOJ 1797
未完待续。
时间: 2024-11-09 00:21:19