POJ1679-The Unique MST(次小生成树+最小瓶颈路 )

来源:互联网 发布:兵营升级数据 率土之滨 编辑:程序博客网 时间:2024/05/18 00:13

题目链接

http://poj.org/problem?id=1679

题意

给定求一张图,判断它的最小生成树是否唯一

思路

只需求出该图的次小生成树,并且判断最小生成树和次小生成树权值和是否相同即可
那么问题就转化成了求次小生成树:先求出最小生成树,然后枚举剩下的m - n +1条边, 将其中一条边(u, v)加入MST中,这样必定u->v之间会形成回路,根据最小生成树的回路性质,回路中权值最大的那条边必定不在最小生成树中,因此我们只需删除MST中u->v权值最大的那条边,即u->v之间的最小瓶颈路
于是可以考虑预处理出任意一对结点之间的最小瓶颈路,可以知道任意一对结点u->v的最小瓶颈路就为MST上u->v的路径。因此,只需求出原图的MST,并且DFS将其转化为有根树并求任意一对结点之间的最小瓶颈路即可

代码

#include <iostream>#include <cstring>#include <stack>#include <vector>#include <set>#include <map>#include <cmath>#include <queue>#include <sstream>#include <iomanip>#include <fstream>#include <cstdio>#include <cstdlib>#include <climits>#include <deque>#include <bitset>#include <algorithm>using namespace std;#define PI acos(-1.0)#define LL long long#define PII pair<int, int>#define PLL pair<LL, LL>#define mp make_pair#define IN freopen("in.txt", "r", stdin)#define OUT freopen("out.txt", "wb", stdout)#define scan(x) scanf("%d", &x)#define scan2(x, y) scanf("%d%d", &x, &y)#define scan3(x, y, z) scanf("%d%d%d", &x, &y, &z)#define sqr(x) (x) * (x)#define pr(x) cout << #x << " = " << x << endl#define lc o << 1#define rc o << 1 | 1#define pl() cout << endlconst int maxn = 10005;int n, m, p[maxn], r[maxn];bool use[maxn];vector<PII> G[105];struct Edge {    int u, v, w;    Edge(int a, int b, int c) : u(a), v(b), w(c) {    }    Edge() {    }} E[maxn];int find(int x) {    return p[x] == x ? x : p[x] = find(p[x]);}bool cmp(Edge x, Edge y) {    return x.w < y.w;}int kruskal() {    for (int i = 1; i <= n; i++) p[i] = i;    int ans = 0;    sort(E, E + m, cmp);    for (int i = 0; i < m; i++) {        int x = E[i].u, y = E[i].v;        x = find(x);        y = find(y);        if (x != y) {            ans += E[i].w;            p[x] = y;            use[i] = 1;            G[E[i].u].push_back(mp(E[i].v, E[i].w));            G[E[i].v].push_back(mp(E[i].u, E[i].w));        }    }    return ans;}const int maxnode = 105;int f[maxnode][maxnode], x;void dfs(int u, int v, int MAX, int w) {    if (v > 0) f[x][u] = max(MAX, w);    for (int i = 0; i < G[u].size(); i++) {        int son = G[u][i].first;        if (son == v) continue;        dfs(son, u, f[x][u], G[u][i].second);    }}int main() {    int T;    scan(T);    while (T--) {        scan2(n, m);        memset(f, 0, sizeof(f));        memset(use, 0, sizeof(use));        for (int i = 0; i < 105; i++) G[i].clear();        for (int i = 0; i < m; i++) {            int x, y, z;            scan3(E[i].u, E[i].v, E[i].w);        }        int mst = kruskal();        for (int i = 1; i <= n; i++) {            x = i;            dfs(i, -1, 0, 0);        }        bool flag = true;        for (int i = 0; i < m; i++) {            if (use[i]) continue;            int from = E[i].u, to = E[i].v;            int mst_ans = max(f[from][to], f[to][from]);            if (mst_ans == E[i].w) {                flag = false;                break;            }        }        if (!flag) puts("Not Unique!");        else printf("%d\n", mst);    }    return 0;}
0 0
原创粉丝点击