1​​题目链接​​。题目大意:给定一个无向图,删除一些边使得图不再连通,求最下的代价。(代价定义为删除的边权和)。

2.首先我们需要判断图是不是联通的,判断无向图是否联通直接并查集即可。若是联通,那么就是求解一个无向图的最小割。如果采用固定原点枚举汇点跑网络流,复杂度达到O(N^5)。无向图的最小割叫做全局最小割,求解全局最小割有专门的SW算法。这道题也是一个模板题。

#include<bits/stdc++.h>
using namespace std;
#pragma warning(disable:4996)
#define inf 99999999
int G[666][666], ans;
int f[666];
int finde(int x)
{
if (x != f[x])
f[x] = finde(f[x]);
return f[x];
}
void make(int a, int b)
{
int x = finde(a);
int y = finde(b);
if (x != y)
f[x] = y;
}
void Mincut(int n)
{
ans = inf;
int node[666], dis[666];
bool use[666];
int i, k, pre;
for (i = 0; i < n; i++)
node[i] = i;
while (n > 1)
{
int maxj = 1;
for (i = 1; i < n; i++)//初始化到已圈集合的割大小
{
dis[node[i]] = G[node[i]][node[0]];
if (dis[node[maxj]] < dis[node[i]])
{
maxj = i;
}
}
pre = 0;
memset(use, false, sizeof(use));
use[node[0]] = true;
for (k = 1; k < n; k++)
{
if (k == n - 1)
{
ans = min(ans, dis[node[maxj]]);
for (i = 0; i < n; i++)
{
G[node[i]][node[pre]] = G[node[pre]][node[i]] += G[node[i]][node[maxj]];
}
node[maxj] = node[--n];
}
use[node[maxj]] = true;
pre = maxj;
maxj = -1;
for (i = 1; i < n; i++)
{
if (!use[node[i]])
{
dis[node[i]] += G[node[i]][node[pre]];
if (maxj == -1 || dis[node[maxj]] < dis[node[i]])
maxj = i;
}
}
}
}
}
int main()
{
int n, m, i;
while (scanf("%d%d", &n, &m) != -1)
{
memset(G, 0, sizeof(G));
for (i = 0; i < n; i++)
{
f[i] = i;
}
while (m--)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
G[a][b] = G[b][a] += c;
make(a, b);
}
int flag = 0;
for (i = 0; i < n; i++)
{
if (finde(i) != finde(0))
flag++;
}
if (flag)
printf("0\n");
else
{
Mincut(n);
printf("%d\n", ans);
}
}
}