日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

POJ 1679 - The Unique MST(次小生成树)

發(fā)布時(shí)間:2025/7/25 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 POJ 1679 - The Unique MST(次小生成树) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目鏈接 https://vjudge.net/problem/POJ-1679

Given a connected undirected graph, tell if its minimum spanning tree is unique.

Definition 1 (Spanning Tree): Consider a connected, undirected graph G = (V, E). A spanning tree of G is a subgraph of G, say T = (V’, E’), with the following properties:
1. V’ = V.
2. T is connected and acyclic.

Definition 2 (Minimum Spanning Tree): Consider an edge-weighted, connected, undirected graph G = (V, E). The minimum spanning tree T = (V, E’) of G is the spanning tree that has the smallest total cost. The total cost of T means the sum of the weights on all the edges in E’.
Input
The first line contains a single integer t (1 <= t <= 20), the number of test cases. Each case represents a graph. It begins with a line containing two integers n and m (1 <= n <= 100), the number of nodes and edges. Each of the following m lines contains a triple (xi, yi, wi), indicating that xi and yi are connected by an edge with weight = wi. For any two nodes, there is at most one edge connecting them.
Output
For each input, if the MST is unique, print the total cost of it, or otherwise print the string ‘Not Unique!’.
Sample Input
2
3 3
1 2 1
2 3 2
3 1 3
4 4
1 2 2
2 3 2
3 4 2
4 1 2
Sample Output
3
Not Unique!

【題意】
給定一張無向圖,判斷這個(gè)圖的最小生成樹是否唯一,如果唯一則輸出最小生成樹的權(quán)值,否則輸出 “Not Unique!”

【思路】
題目實(shí)際上想問的是次小生成樹的權(quán)值,如果次小生成樹的權(quán)值和最小生成樹一樣,那么最小生成樹不唯一。最小生成樹可以在求出每對(duì)點(diǎn)之間的最小瓶頸路后枚舉剩下的邊求出。具體做法是先求最小生成樹,同時(shí)用dfs求出任意兩點(diǎn)的最小瓶頸路,然后枚舉所有不在最小生成樹中的邊,假設(shè)這條邊的端點(diǎn)是u和v,用這條邊去替換原來最小生成樹中u,v的最小瓶頸路,迭代取最小值。所以次小生成樹就是最小瓶頸路的一個(gè)簡單應(yīng)用。

#include<cstdio> #include<vector> #include<cstring> #include<iostream> #include<algorithm> using namespace std;const int inf = 0x3f3f3f3f; const int maxn = 105; const int maxm = 10050;struct Edge {int from, to, dist;Edge(int f = 0, int t = 0, int d = 0) :from(f), to(t), dist(d) {}bool operator<(const Edge& e) const {return dist < e.dist;} };int n, m; int par[maxn]; bool used[maxn];//dfs的訪問標(biāo)記數(shù)組 bool vis[maxm];//某條邊是否使用過 int f[maxn][maxn]; vector<Edge> edges, g[maxn];int find(int x) { return par[x] == x ? x : par[x] = find(par[x]); }int kruscal() {int cnt = 0, ans = 0;for (int i = 0; i < n; ++i) {par[i] = i;g[i].clear();}for (int i = 0; i < m; ++i) {int u = edges[i].from;int v = edges[i].to;int x = find(u);int y = find(v);if (x != y) {par[x] = y;ans += edges[i].dist;vis[i] = true;g[u].push_back(Edge(u, v, edges[i].dist));g[v].push_back(Edge(v, u, edges[i].dist));if (++cnt == n - 1) break;}}return ans; }void dfs(int u) {used[u] = 1;for (int i = 0; i < g[u].size(); ++i) {int v = g[u][i].to;if (!used[v]) {for (int x = 0; x < n; ++x) {if (used[x]) f[x][v] = f[v][x] = max(f[x][u], g[u][i].dist);}dfs(v);}} }int main() {int t;scanf("%d", &t);while (t--) {scanf("%d%d", &n, &m);edges.clear();memset(vis, 0, sizeof(vis));for (int i = 0; i < m; ++i) {int u, v, c;scanf("%d%d%d", &u, &v, &c);--u, --v;edges.push_back(Edge(u, v, c));}sort(edges.begin(), edges.end());int mst = kruscal();memset(used, 0, sizeof(used));memset(f, 0, sizeof(f));dfs(0);int ans = inf;//枚舉所有沒有用過的邊for (int i = 0; i < m; ++i) {if (!vis[i]) { ans = min(ans, mst - f[edges[i].from][edges[i].to] + edges[i].dist);}}if (ans == mst) printf("Not Unique!\n");else printf("%d\n", mst);}return 0; }

轉(zhuǎn)載于:https://www.cnblogs.com/wafish/p/10465403.html

總結(jié)

以上是生活随笔為你收集整理的POJ 1679 - The Unique MST(次小生成树)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。