题目大意:要求你求出最小生成树和次小生成树
解题思路:比较裸的题
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int MAXNODE = 510;
const int MAXEDGE = 1000010;
const int INF = 0x3f3f3f3f;
struct Edge {
int u, v, d;
}E[MAXEDGE];
vector<Edge> G[MAXNODE];
int n, m;
bool visNode[MAXNODE], visEdge[MAXEDGE];
int f[MAXNODE], maxcost[MAXNODE][MAXNODE];
void init() {
for (int i = 0; i < m; i++) scanf("%d%d%d", &E[i].u, &E[i].v, &E[i].d);
}
bool cmp(const Edge &a, const Edge &b) {
return a.d < b.d;
}
void dfs(int s, int u, int Max, int fa) {
maxcost[s][u] = max(maxcost[s][u], Max);
for (int i = 0; i < G[u].size(); i++) {
int v = G[u][i].v;
if (v == fa) continue;
int tmp = max(Max, G[u][i].d);
dfs(s, v, tmp, u);
}
}
int find(int x) {
return x == f[x] ? x : f[x] = find(f[x]);
}
void solve() {
for (int i = 1; i <= n; i++) {
f[i] = i; G[i].clear();
visNode[i] = false;
}
memset(visEdge, 0, sizeof(visEdge));
sort(E, E + m, cmp);
int cnt = 0, ans = 0;
for (int i = 0; i < m; i++) {
int tx = find(E[i].u);
int ty = find(E[i].v);
if (tx != ty) {
ans += E[i].d;
visEdge[i] = true;
visNode[E[i].u] = visNode[E[i].v] = true;
f[tx] = ty;
G[E[i].u].push_back(E[i]);
swap(E[i].u, E[i].v);
G[E[i].u].push_back(E[i]);
cnt++;
}
}
for (int i = 1; i <= n; i++)
if (!visNode[i]) {
printf("Cost: %d\n", -1);
printf("Cost: %d\n", -1);
return ;
}
if (cnt == m) {
printf("Cost: %d\n", ans);
printf("Cost: %d\n", -1);
return ;
}
memset(maxcost, 0, sizeof(maxcost));
for (int i = 1; i <= n; i++)
dfs(i, i, 0, -1);
int Min = INF;
for (int i = 0; i < m; i++)
if (!visEdge[i]) {
Min = min(Min, E[i].d - maxcost[E[i].u][E[i].v]);
}
printf("Cost: %d\n", ans);
printf("Cost: %d\n", ans + Min);
}
int main() {
while (scanf("%d%d", &n, &m) != EOF) {
init();
solve();
}
return 0;
}