The definition of the secondary niche as a tree
the g= (v,e,w) is a connected undirected graph, and T is a minimum spanning tree of graph G. If there is another tree T1, full
The foot does not exist the tree T ', ω (t ') <ω (T1), it is said that T1 is the second niche tree of Fig G.
Algorithm for solving sub-niche tree
Convention: A set of new spanning trees made by T for a feasible exchange, called the neighborhood set of a tree T, which is recorded as N (t).
Theorem 3: Set T to be the smallest spanning tree of graph G if T1 satisfies Ω (T1) =min{ω (T ') | T ' ∈n (t)}, then T1 is g
The second niche into a tree.
Proof: If T1 is not a secondary niche tree of G, then there must be another spanning tree t ', t ' =t that makes
Ω (t) ≤ω (t ') <ω (T1), defined by the T1 t that does not belong to N (t), then
E (t ')/e (t) ={a1,a2
1,......, at},e (t)/e (t ') ={b1,b2,......, bt}, where t≥2. According to the Lemma 1 know that there is a
The permutation bi1,bi2,......, bit so that the t+aj-bij is still the spanning tree of G and belongs to N (T), so Ω (AJ) ≥ω (bij),
So Ω (T ') ≥ω (t+aj-bij) ≥ω (T1), so contradictory. So T1 is the second niche tree of Fig G.
Through the above theorem, we have the basic idea of solving the problem of the secondary niche tree.
First, the minimum spanning tree T of the graph is obtained. Time complexity O (vlog2v+e)
Then, we find the right value and the smallest spanning tree of T, that is, the secondary niche of fig G is tree.
If it's just a simple enumeration, it's a very high degree of complexity. First, the complexity of enumerating two edges is O (VE), and then determine whether the exchange
The feasible degree of complexity is O (V), then the total time complexity is O (v2e). Such algorithms appear to be blind. After a simple
Analysis is not difficult to find, each add a not on the edge of the tree, can always form a ring, only to delete the ring on a side, to
Guaranteed after the exchange is still a spanning tree, and the deletion of the edge of the larger weight, the new generated tree weight and the smaller. We can
In order to reduce the complexity of the O (VE). It's a big step forward, but it's still not good enough.
Looking back at the previous model-the minimum limit spanning tree-we have faced similar problems and eventually adopted dynamic rules
The method of the stroke avoids the repetition calculation, which greatly reduces the complexity. For the subject, we can adopt a similar idea. First
First, do a one-step preprocessing to find the maximum weight on the path between each of the two nodes in the tree, and then the enumeration diagram is not
The edge of the tree, with just the pretreatment, we can use O (1) time to get the maximum edge of the right value on the ring formed.
How to preprocess it? Because this is a tree, so do not need any advanced algorithm, as long as the simple BFS can.
The time complexity of preprocessing is O (V2).
In this way, the time complexity of this step is reduced to O (V2).
To sum up, the time complexity of the second niche into a tree is O (V2).
Practice
topic:
Topic Description:
Minimum spanning tree We all know that the second niche tree is the weight of the tree in the figure and the second small tree, this value may equal to the minimum spanning tree weight and, your task is to design an algorithm to calculate the minimum spanning tree.
Input:
There are multiple sets of data, the first line a positive integer t, which indicates the T-group data.
The first row of each set of data has two integers n and m (2<=n<=100), followed by m rows, three positive integers per line s,e,w, and W for the two-way path of S to E.
Output:
Output the secondary niche into a tree value if there is no output-1.
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:
4
6
AC code (note written more clearly):
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX 100000 int FATHER[210]; and search set int visit[210]; A subscript int windex that records the edges used by the minimum spanning tree;
Record the number of minimum spanning trees used to the edge typedef struct Node {int St, ed, W;
node;
/** * preprocessing and look-up set array/void Preprocess () {int i, Len = sizeof (father)/sizeof (father[0));
for (i = 0; i < len; i + +) {Father[i] = i; }/** * Kruskal uses the greedy algorithm to sort the edge weights from small to large/int cmp (const void *p, const void *q) {const node
*a = p;
Const node *B = q;
Return a->w-b->w;
/** * and search the set to find the starting node, path compression optimization */int findparent (int x) {int parent;
if (x = = Father[x]) {return x;
Parent = Findparent (father[x]);
FATHER[X] = parent;
return to parent;
/** * minimum spanning tree/int mintree (node *points, int m, int n) {preprocess (); int I, count, Flag, PA, PB;
for (i = count = Flag = Windex = 0; i < m i + +) {pa = findparent (points[i].st);
PB = Findparent (Points[i].ed);
if (PA!= pb) {Visit[windex + +] = i;
FATHER[PA] = PB;
Count + +;
} if (count = = n-1) {flag = 1;
Break
} return flag; /** * Find the second niche into a tree/int secmintree (node *points, int m, int n) {int i, J, Min, TMP, PA, PB, Count
, Flag;
for (i = 0, min = MAX; i < Windex i + +) {preprocess (); The second niche into a tree for (j = count = TMP = flag = 0; j < m; J + +) {if (J!= Visit[i]) {PA = Findpare
NT (Points[j].st);
PB = Findparent (Points[j].ed);
if (PA!= pb) {count + +;
TMP + = POINTS[J].W;
FATHER[PA] = PB;
} if (count = = n-1) {flag = 1;
Break }} if (Flag && tmp < min) min = tmp; Min = (min = MAX)?
-1:min;
return min;
int main (void) {int i, T, N, M, flag, Min;
Node *points;
scanf ("%d", &t);
while (T-) {scanf ("%d%d", &n, &m);
Points = (node *) malloc (sizeof (node) * m);
for (i = 0; i < m + +) {scanf ("%d%d%d", &points[i].st, &points[i].ed, &POINTS[I].W);
} qsort (points, M, sizeof (POINTS[0)), CMP);
Flag = Mintree (points, M, N);
if (flag = = 0) {//cannot generate the minimum spanning tree printf (" -1\n");
Continue
else {min = Secmintree (points, M, N);
printf ("%d\n", min);
Free (points);
return 0;
}