POJ 1679 the Unique MST "sub-niche into a tree"

Source: Internet
Author: User

The Unique MST
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 21119 Accepted: 7451

Description

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

Definition 1 (Spanning Tree): Consider a connected, undirected graph G = (V, E). A spanning tree of 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, which has the and 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 <=), the number of test cases. Each case represents a graph. It begins with a line containing, integers n and m (1 <= n <=), the number of nodes and edges. Each of the following m lines contains a triple (xi, Yi, WI), indicating that Xi and Yi is connected by an edge with Weig HT = wi. For any of the nodes, there is at the most one edge connecting them.

Output

For each input, if the MST was unique, print the total cost of it, or otherwise print the string ' not unique! '.

Sample Input

23 31 2 12 3 23 1 34 41 2 22 3 23 4 24 1 2

Sample Output

3Not unique!

Test instructions: Find out if the minimum spanning tree is unique.

What is a spanning tree: A number that contains a 1~n,n node

What is a sub-niche into a tree is a tree in which the tree (weights) in the graph is only larger than the minimum spanning tree (the weight value).

Analysis: Set T as a minimum spanning tree of graphs, then we think that as long as we can find not a side in T (u,v) to replace T (U,V) then this replaced tree must be a spanning tree, and because the smallest spanning tree of any two nodes of the edge is relatively shortest, Then we only need to constantly change the words (each time only one edge), which formed a minimum spanning tree to change the set of spanning tree, called the neighborhood set of T, then we can not be difficult to find that the sub-niche into a tree must be in the neighborhood of T, so we just need to enumerate T neighbor set to find the next niche into a tree Then determine if it is equal to the minimum spanning tree.

So here's the problem: the excavator technology which is strong. How do you ask for a cough?

Method: Each time an edge in T is enumerated, find the only path to connect U and V in T (definitely unique, think about why), find the longest edge in the path, store it with Max "U" "V", and then enumerate the edges you are not in T, V, replace the longest edge max "U" "V", constantly enumerate,

It's a little abstract, I'm talking about my understanding.


The picture is a little ugly, but I can express my meaning. MST is the smallest spanning tree, SST is the sub-niche into a tree u= 2, v = 3.

That's what happens after the conversion.

In fact, there are two kinds of solutions to this problem, one is to find out the sub-niche into a tree, one is to mark the smallest generation of the edge of the tree, one time to delete the marked edge, to find the minimum spanning tree,

Note: This is just my personal (small rookie one) understanding, welcome Master to advise!!

Reference: http://www.cnblogs.com/dongsheng/articles/2617186.html

Code 1 (secondary niche into a tree):

#include <cstdio> #include <cstring>//#include <algorithm>const int M = 105;const int INF = 0x3f3f3f3f;u  Sing namespace Std;int map[m][m], N, M, Low[m];int pre[m], max[m][m];  The pre is the last point, Max is the longest path to store bool Con[m][m], vis[m]; The con array is the tag in the smallest spanning tree of the edge int Max (int a, int b) {return a>b?a:b;}    int Prim () {memset (Vis, 0, sizeof (VIS));    memset (max, 0, sizeof (max));    Memset (con, false, sizeof (con));    int I, J, pos, min, sum = 0;    pos = 1;        for (i = 1; I <= n; i + +) {Low[i] = Map[pos][i];    Pre[i] = pos;    } Vis[pos] = 1;        for (i = 1; i < n; i + +) {min = INF;            for (j = 1; J <= N; j + +) {if (!vis[j]&&min > Low[j]) {min = low[j]; pos = j;        }} if (min = = INF) return-1;        sum + = min;        Vis[pos] = 1;        Con[pre[pos]][pos] = Con[pos][pre[pos]] = 1;  Max[pre[pos]][pos] = Max[pos][pre[pos]] = min; First store min for (j = 1; J <= N; j + +) {//the cycle here is to find out the longest side, think carefullyI want to ha ~ ~ with the Yes DP Max[j][pos] = MAX (Max[pre[pos]][pos], Max[j][pos]); } for (j = 1; J <= N; j + +) {if (!vis[j]&&map[pos][j] < low[j]) {Low[j] = ma                P[POS][J];            PRE[J] = pos; }}} return sum;}    int main () {int t;    scanf ("%d", &t);        while (T--) {scanf ("%d%d", &n, &m);        int I, J;        for (i = 0; i < M; i + +) for (j = 0; J < m; j + +) map[i][j] = INF;        int A, b, C;            for (i = 0; i < m; i + +) {scanf ("%d%d%d", &a, &b, &c);        MAP[A][B] = map[b][a] = C;        } int res = PRIM ();        int flag = 0; for (i = 1; I <= n; i + +) {for (j = 1; J <= N; j + +) {if (con[i][j]| | MAP[I][J] = = INF) continue;                Here is the edge of the enumeration minimum spanning tree, int ans = map[i][j]-max[i][j];                    if (ans = = 0) {flag = 1;           Break     }} if (flag) break;        } if (flag) printf ("Not unique!\n");    else printf ("%d\n", res); } return 0;}

Code Listing 2:

#include <cstdio> #include <cstring> #include <algorithm>const int M = 105;using namespace Std;struct    node{int from, to, W; BOOL Flag;}    S[m*m];int N, M, fat[m];int f (int x) {if (x! = Fat[x]) fat[x] = f (fat[x]); return fat[x];} int CMP (Node A, Node B) {return A.W < B.W;}    int Kruskal () {int i, min = 0, cou = 0;    for (i = 0; i < M; i + +) fat[i] = i;        for (i = 0; i < m; i + +) {int x = f (s[i].from); int y = f (s[i].to);            if (x! = y) {min + = S[I].W;            Fat[x] = y;            S[i].flag = true;        Cou + +;    }} if (cou! = n-1) return-1; return min;}    int kruskalsst (int v) {int i, min = 0, cou = 0;    for (i = 0; i < M; i + +) fat[i] = i;        for (i = 0; i < m; i + +) {if (v = = i) continue; int x = f (s[i].from);        int y = f (s[i].to);            if (x! = y) {min + = S[I].W;            Fat[x] = y;        Cou + +;    }} if (cou! = n-1) return-1; return min;}  int main () {  int t;    scanf ("%d", &t);        while (T--) {scanf ("%d%d", &n, &m);        memset (s, 0, sizeof (s));        int i;        for (i = 0; i < m; i + +) {scanf ("%d%d%d", &s[i].from, &s[i].to, &AMP;S[I].W);        } sort (S, s+n, CMP);        int res = Kruskal ();        if (res = =-1) {printf ("not unique!\n"); continue;        } int flag = 0;                for (i = 0; i < m; i + +) {if (s[i].flag) {int ans = kruskalsst (i);                if (res = = ans) {flag = 1; break;        }}} if (flag) printf ("Not unique!\n");    else printf ("%d\n", res); } return 0;}


POJ 1679 the Unique MST "sub-niche into a tree"

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.