題意:都是求全局最小割
思路:訓練時發現網絡流是我們隊伍一大缺陷,就看了一天多的網絡流,然後也學會了Stoer-Wagner算法
要注意的是輸入會有重邊,所以不能只賦值一次,這個做任何圖論題都要注意
hdu 3691:http://acm.hdu.edu.cn/showproblem.php?pid=3691
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 105;
const int inf = 0x3f3f3f3f;
struct Stoer_Wagner
{
int n, g[maxn][maxn], b[maxn], dist[maxn];
void init(int n, int w[maxn][maxn])
{
this->n = n;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
g[i][j] = w[i][j];
}
}
}
int Min_Cut_Phase(int ph, int &x, int &y)
{
int t = 1;
int i, j;
b[t] = ph;
for(i = 1; i <= n; i++)
if(b[i] != ph)
dist[i] = g[1][i];
for(i = 1; i < n; i++)
{
x = t;
for(t = 0, j = 1; j <= n; j++)
if(b[j] != ph && (!t || dist[j] > dist[t]))
t = j;
b[t] = ph;
for(j = 1; j <= n; j++)
if(b[j] != ph)
dist[j] += g[t][j];
}
return y = t, dist[t];
}
void Merge(int x, int y)
{
if(x > y)
swap(x, y);
for(int i = 1; i <= n; i++)
{
if(i != x && i != y)
g[i][x] += g[i][y], g[x][i] += g[i][y];
}
if(y == n)
return ;
for(int i = 1; i < n; i++)
{
if(i != y)
{
swap(g[i][y], g[i][n]);
swap(g[y][i], g[n][i]);
}
}
}
int Min_Cut()
{
int ret = inf, x, y;
memset(b, 0, sizeof(b));
for(int i = 1; n > 1; i++, n--)
{
ret = min(ret, Min_Cut_Phase(i, x, y));
Merge(x, y);
}
return ret;
}
};
Stoer_Wagner sw;
int w[maxn][maxn];
int main()
{
int n, m;
while(~scanf("%d%d", &n, &m))
{
int u, v, c;
memset(w, 0, sizeof(w));
for(int i = 1; i <= m; i++)
{
scanf("%d%d%d", &u, &v, &c);
u++, v++;
w[u][v] += c;
w[v][u] += c;
}
sw.init(n, w);
int ans = sw.Min_Cut();
printf("%d\n", ans);
}
return 0;
}
hdu 3002: http://acm.hdu.edu.cn/showproblem.php?pid=3002
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 105;
const int inf = 0x3f3f3f3f;
struct Stoer_Wagner
{
int n, g[maxn][maxn], b[maxn], dist[maxn];
void init(int n, int w[maxn][maxn])
{
this->n = n;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
g[i][j] = w[i][j];
}
}
}
int Min_Cut_Phase(int ph, int &x, int &y)
{
int t = 1;
int i, j;
b[t] = ph;
for(i = 1; i <= n; i++)
if(b[i] != ph)
dist[i] = g[1][i];
for(i = 1; i < n; i++)
{
x = t;
for(t = 0, j = 1; j <= n; j++)
if(b[j] != ph && (!t || dist[j] > dist[t]))
t = j;
b[t] = ph;
for(j = 1; j <= n; j++)
if(b[j] != ph)
dist[j] += g[t][j];
}
return y = t, dist[t];
}
void Merge(int x, int y)
{
if(x > y)
swap(x, y);
for(int i = 1; i <= n; i++)
{
if(i != x && i != y)
g[i][x] += g[i][y], g[x][i] += g[i][y];
}
if(y == n)
return ;
for(int i = 1; i < n; i++)
{
if(i != y)
{
swap(g[i][y], g[i][n]);
swap(g[y][i], g[n][i]);
}
}
}
int Min_Cut()
{
int ret = inf, x, y;
memset(b, 0, sizeof(b));
for(int i = 1; n > 1; i++, n--)
{
ret = min(ret, Min_Cut_Phase(i, x, y));
Merge(x, y);
}
return ret;
}
};
Stoer_Wagner sw;
int w[maxn][maxn];
int main()
{
int n, m;
while(~scanf("%d%d", &n, &m))
{
int u, v, c;
memset(w, 0, sizeof(w));
for(int i = 1; i <= m; i++)
{
scanf("%d%d%d", &u, &v, &c);
u++, v++;
w[u][v] += c;
w[v][u] += c;
}
sw.init(n, w);
int ans = sw.Min_Cut();
printf("%d\n", ans);
}
return 0;
}
poj 2914:http://poj.org/problem?id=2914
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 505;
const int inf = 0x3f3f3f3f;
struct Stoer_Wagner
{
int n, g[maxn][maxn], b[maxn], dist[maxn];
void init(int n, int w[maxn][maxn])
{
this->n = n;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
g[i][j] = w[i][j];
}
}
}
int Min_Cut_Phase(int ph, int &x, int &y)
{
int t = 1;
int i, j;
b[t] = ph;
for(i = 1; i <= n; i++)
if(b[i] != ph)
dist[i] = g[1][i];
for(i = 1; i < n; i++)
{
x = t;
for(t = 0, j = 1; j <= n; j++)
if(b[j] != ph && (!t || dist[j] > dist[t]))
t = j;
b[t] = ph;
for(j = 1; j <= n; j++)
if(b[j] != ph)
dist[j] += g[t][j];
}
return y = t, dist[t];
}
void Merge(int x, int y)
{
if(x > y)
swap(x, y);
for(int i = 1; i <= n; i++)
{
if(i != x && i != y)
g[i][x] += g[i][y], g[x][i] += g[i][y];
}
if(y == n)
return ;
for(int i = 1; i < n; i++)
{
if(i != y)
{
swap(g[i][y], g[i][n]);
swap(g[y][i], g[n][i]);
}
}
}
int Min_Cut()
{
int ret = inf, x, y;
memset(b, 0, sizeof(b));
for(int i = 1; n > 1; i++, n--)
{
ret = min(ret, Min_Cut_Phase(i, x, y));
Merge(x, y);
}
return ret;
}
};
Stoer_Wagner sw;
int w[maxn][maxn];
int main()
{
int n, m;
while(~scanf("%d%d", &n, &m))
{
int u, v, c;
memset(w, 0, sizeof(w));
for(int i = 1; i <= m; i++)
{
scanf("%d%d%d", &u, &v, &c);
u++, v++;
w[u][v] += c;
w[v][u] += c;
}
sw.init(n, w);
int ans = sw.Min_Cut();
printf("%d\n", ans);
}
return 0;
}