a. MST:
Provided undirected graph G = ( V , E ),to connect every point in V set, there is a set which is E's subset of edges. The total lengths of all edges in subset which is the Minimal Spanning Tree;
b.Kruskal theory:
Sort the E set ( int which every edge described by two points a and b ) by value ( length ), then ergodic the whole E set,if a has connected b, give it up and next, otherwise , connect a and b ;
c.Union-Find set:
when finding the father of one pointer, change their father to root by the way (using recursion theory ): 路径压缩
UnionFind( x ):
if ( x == Father[x] )
return x;
return Father[x] = UnionFind( Father[x] );
d. Graph G = ( V, E ):
V is the set of points; such as V = { a, b, c, d } n items
E is the set of edges: such E = { (a,b), (a,c), (a,d ),(b,c), (b,d)...} s <= n * ( n - 1 ) / 2;
例题:HDU-1233
Time Limit: 4000 / 2000 MS (Java / Others) Memory Limit: 65536 / 32768 K (Java / Others)
Total Submission(s): 6742 Accepted Submission(s): 3087
Problem Description
某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
Input
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N - 1 ) / 2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。
当N为0时,输入结束,该用例不被处理。
Output
对每个测试用例,在1行里输出最小的公路总长度。
Sample Input
3
1 2 1
1 3 2
2 3 4
4
1 2 1
1 3 4
1 4 1
2 3 3
2 4 2
3 4 5
0
Sample Output
3
5
#include<iostream>
#include<iomanip>
#include<string.h>
#include<algorithm>
using namespace std;
#define MAX 105
#define MAXN 5000
struct Edge
{
int a, b, Value;
bool flag;
}Edges[MAXN];
int Father[MAX], Pointer[MAXN]; //1.Pointer : it is convenient to sort the points rather than Structs.
int cmp( int a, int b )
{
return Edges[a].Value <= Edges[b].Value;
}
int UnionFind( int x ) //2.This is the point:Union their father ,which can save much time the next time finding father.
{
if( x == Father[x] )
return x;
return Father[x] = UnionFind( Father[x] );
}
int Kruskal( int n )
{
int result = 0;
for( int i = 0; i < n ; i++ )
{
int r = Pointer[i];
int fa = UnionFind( Edges[r].a ); //3.This is the lime light: one father can have two sons, but one child can't have two fathers;
int fb = UnionFind( Edges[r].b );
if( fa != fb )
{
Father[fa] = Father[fb]; //4.Union their father rather than the children!!!
Edges[r].flag = 1;
result += Edges[r].Value;
}
}
return result;
}
int main()
{
int n;
while( cin >> n && n )
{
for( int i = 0; i < MAXN; i ++ )
{
Edges[i].flag = 0;
Pointer[i] = i;
}
for( int i = 0; i < MAX; i++ )
Father[i] = i;
int s = n * ( n - 1 ) / 2;
for( int i = 0; i < s; i++ )
cin >> Edges[i].a >> Edges[i].b >> Edges[i].Value;
sort( Pointer, Pointer + s, cmp );
cout << Kruskal( s ) << endl;
}
}