题意:
最少删去多少条边使得图不再是单个双连通分量。
思路:
1.最小割思路,n 次网络流做法,TLE
2.Stoer-Wagner算法(模板),8000+ms,很有压力。
Stoer-Wagner算法详解见:http://blog.csdn.net/i_love_home/article/details/9698791
poj 2914 第三个案例分析见:http://blog.sina.com.cn/s/blog_700906660100v7vb.html
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 550;
const int inf = 1000000000;
int n, r;
int edge[maxn][maxn], dist[maxn];
bool vis[maxn], bin[maxn];
void init()
{
memset(edge, 0, sizeof(edge));
memset(bin, false, sizeof(bin));
}
int contract( int &s, int &t ) // 寻找 s,t
{
memset(dist, 0, sizeof(dist));
memset(vis, false, sizeof(vis));
int i, j, k, mincut, maxc;
for(i = 1; i <= n; i++)
{
k = -1; maxc = -1;
for(j = 1; j <= n; j++)if(!bin[j] && !vis[j] && dist[j] > maxc)
{
k = j; maxc = dist[j];
}
if(k == -1)return mincut;
s = t; t = k;
mincut = maxc;
vis[k] = true;
for(j = 1; j <= n; j++)if(!bin[j] && !vis[j])
dist[j] += edge[k][j];
}
return mincut;
}
int Stoer_Wagner()
{
int mincut, i, j, s, t, ans;
for(mincut = inf, i = 1; i < n; i++)
{
ans = contract( s, t );
bin[t] = true;
if(mincut > ans)mincut = ans;
if(mincut == 0)return 0;
for(j = 1; j <= n; j++)if(!bin[j])
edge[s][j] = (edge[j][s] += edge[j][t]);
}
return mincut;
}
int main() {
int u, v, c;
while( ~scanf("%d%d", &n, &r ) )
{
init();
while( r-- )
{
scanf( "%d%d%d", &u, &v, &c );
u++; v++;
edge[u][v] = (edge[v][u] += c);
}
printf( "%d\n", Stoer_Wagner() );
}
return 0;
}