Link:http://poj.org/problem?
id=1679
Test Instructions: tells you that there are n points, M-bars, and M-Edge information (start, end, weight). Infer if the minimum spanning tree is unique
It was done in a different way before. The complexity is up to O (n^3), and then once again with a sub-niche into a tree. Complexity O (n^2+m).
First of all, the method of the niche into a tree.
Sub-niche into a tree: to find the smallest spanning tree, the use of the edge to mark, at this time to join the additional edge into the ring must be formed, delete the second largest edge of the ring (that ring in the spanning tree on the largest edge), plus the weight of the extra edge, enumerate each additional edge, take the minimum value, is the second niche The same method can be used to find the K niche into a tree and infer whether the K niche tree is unique.
#include <cstring> #include <string> #include <fstream> #include <iostream> #include < iomanip> #include <cstdio> #include <cctype> #include <algorithm> #include <queue> #include <map> #include <set> #include <vector> #include <stack> #include <ctime> #include < cstdlib> #include <functional> #include <cmath>using namespace std; #define PI ACOs ( -1.0) #define MAXN 50100#define EPS 1e-7#define INF 0x7fffffff#define llinf 0x7fffffffffffffff#define seed 131#define MOD 1000000007#define ll long long#define ull unsigned ll#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1struct node{int u,v,w; int used;} edge1[10010];struct edge{int u,v,w,next;} edge[20010];struct node{int u,maxm;}; int Head[110],vis[110],father[110];int maxm[110][110];int n,m,cnt;void add_edge (int a,int b,int c) {edge[cnt].u = A; EDGE[CNT].V = b; EDGE[CNT].W = C; Edge[cnt].next = Head[a]; Head[a] = cnt++;} int Find (int x) { int t = x; while (t! = father[t]) t = father[t]; int k = x; while (k! = t) {int temp = father[k]; Father[k] = t; K = temp; } return t;} int Kruskal () {int i,j; int num = 0, sum = 0; for (i = 0; I <= N; i++) father[i] = i; for (i = 0; i < m; i++) {int xx = Find (edge1[i].u); int yy = Find (EDGE1[I].V); if (xx! = yy) {Add_edge (edge1[i].u, EDGE1[I].V, EDGE1[I].W); Add_edge (EDGE1[I].V, edge1[i].u, EDGE1[I].W); FATHER[XX] = yy; sum + = EDGE1[I].W; edge1[i].used = 1; num++; if (num >= n-1) break; }} return sum;} void BFs (int src) {int i,j; memset (Vis, 0, sizeof (VIS)); queue<node>q; NODE t1,t2; T1.U = src; T1.MAXM = 0; Q.push (t1); VIS[SRC] = 1; while (!q.empty ()) {T1 = Q.front (); Q.pop (); for (i = head[t1.u]; I! =-1; i = edge[i].next) {t2.u = EDGE[I].V; T2.MAXM = EDGE[I].W; if (!vis[t2.u]) {vis[t2.u] = 1; if (T1.maxm > T2.maxm) t2.maxm = T1.MAXM; MAXM[SRC][T2.U] = T2.MAXM; Q.push (T2); }}}}int Main () {int t,i,j; int a,b,c; scanf ("%d", &t); while (t--) {scanf ("%d%d", &n, &m); for (i = 0; i < m; i++) {scanf ("%d%d%d", &edge1[i].u, &EDGE1[I].V, &EDGE1[I].W); edge1[i].used = 0; } memset (Head,-1,sizeof (head)); CNT = 0; int ans1 = Kruskal (); for (i = 1; I <= n; i++) BFS (i); int ans2 = INF; for (i = 0; i < m; i++) {if (!edge1[i].used) {int temp = ANS1-MAXM[EDGE1[I].U][EDGE1[I].V] + EDGE1[I].W; if (Temp < ANS2) Ans2 = temp; }} if (ANS1!=ANS2) printf ("%d\n", ans1); Else puts ("not unique!"); } return 0;}
Cut- Edge enumeration method: for each side the false is provided with the edge of his equal weight value. Then make a mark and then go through Kruskal or prim to find the minimum spanning tree weights. Then for each edge that has been used and has an equal edge mark, delete it, then go through Kruskal or prim, assuming that at this point the minimum spanning tree weights are the same as the first, then the minimum spanning tree is not unique. Otherwise, the minimum spanning tree is unique.
#include <cstring> #include <string> #include <fstream> #include <iostream> #include < iomanip> #include <cstdio> #include <cctype> #include <algorithm> #include <queue> #include <map> #include <set> #include <vector> #include <stack> #include <ctime> #include < cstdlib> #include <functional> #include <cmath>using namespace std; #define PI ACOs ( -1.0) #define MAXN 110000#define EPS 1e-7#define INF 0x7fffffff#define seed 131#define ll long long#define ull unsigned ll#define lson l,m,rt <<1#define rson m+1,r,rt<<1|1struct node{int u,v,dis; int Used,equa,del;} Edge[maxn];int father[105],vis[105];int N,m,flag,ans;bool CMP (node X,node y) {return x.dis<y.dis;} int find (int x) {int t = x; while (father[t]!=t) t = father[t]; int k = x; while (k!=t) {int temp = father[k]; Father[k] = t; K = temp; } return t;} int Kruskal () {int i,j=0; int sum = 0; for (I=1;I≪=n;i++) Father[i] = i; for (i=0;i<m;i++) {if (Edge[i].del) continue; int a = find (EDGE[I].U); int b = Find (EDGE[I].V); if (a!=b) {Father[a] = b; sum + = Edge[i].dis; j + +; if (flag) edge[i].used = 1; if (j>=n-1) break; }} return sum;} int main () {int t,i,j; scanf ("%d", &t); while (t--) {flag = 1; scanf ("%d%d", &n,&m); for (i=0;i<m;i++) {scanf ("%d%d%d", &edge[i].u,&edge[i].v,&edge[i].dis); edge[i].used = Edge[i].equa = Edge[i].del = 0; } for (i=0;i<m;i++) {for (j=0;j<m;j++) {if (i==j) continue; if (Edge[i].dis = = Edge[j].dis) Edge[i].equa = 1; }} sort (edge,edge+m,cmp); int ans1 = Kruskal (); Flag = 0; for (i=0;i<m;i++) {if (Edge[i].used&&edge[i].equa) {Edge[i].del =1; int ans2 = Kruskal (); if (ans2==ans1) {printf ("not unique!\n"); Break }}} if (i>=m) printf ("%d\n", ans1); } return 0;}
Poj--1679--the unique MST "infer if MST is unique"