本题思路:模版的次小生成树问题,输出MST and Second_MST的值。
参考代码:
#include <cstdio> #include <cstring> #include <algorithm> #include <cstring> #include <vector> using namespace std; const int maxn = 100 + 5, maxe = 100 * 100 / 2 + 5, INF = 0x3f3f3f3f; int n, m, Max[maxn][maxn], pir[maxn]; struct Edge { int u, v, w; bool vis; }edge[maxe]; vector<int> G[maxn]; bool cmp(const Edge &a, const Edge &b) { return a.w < b.w; } int Find(int x) { if(x == pir[x]) return x; return pir[x] = Find(pir[x]); } int Kruskal() { sort(edge + 1, edge + m + 1, cmp); for(int i = 1; i <= n; i ++) { G[i].clear(); pir[i] = i; G[i].push_back(i); } int cnt = 0, ans = 0; for(int i = 1; i <= m; i ++) { int fx = Find(edge[i].u), fy = Find(edge[i].v); if(cnt == n - 1) break; if(fx != fy) { cnt ++; int len_fx = G[fx].size(), len_fy = G[fy].size(); edge[i].vis = true; ans += edge[i].w; for(int j = 0; j < len_fx; j ++) { for(int k = 0; k < len_fy; k ++) { Max[G[fx][j]][G[fy][k]] = Max[G[fy][k]][G[fx][j]] = edge[i].w; } } pir[fx] = fy; for(int j = 0; j < len_fx; j ++) G[fy].push_back(G[fx][j]); } } if(cnt < n - 1) return INF; else return ans; } int Second_Kruskal(int MST) { int ans = INF; for(int i = 1; i <= m; i ++) { if(!edge[i].vis) ans = min(ans, MST + edge[i].w - Max[edge[i].u][edge[i].v]); } return ans; } int main () { int t; scanf("%d", &t); while(t --) { scanf("%d %d", &n, &m); for(int i = 1; i <= m; i ++) { scanf("%d %d %d", &edge[i].u, &edge[i].v, &edge[i].w); edge[i].vis = false; } int MST = Kruskal(); int Second_MST = Second_Kruskal(MST); printf("%d %d ", MST, Second_MST); } return 0; }