仔细想想这就是一道最裸的最小生成树题目
这里给出prim和kruscal两种方法计算
当然因为这题目是密集边
所以其实prim算法更加好一点的
prim:
1 /* 2 最小生成树,prim算法 3 */ 4 #include <cstdio> 5 #include <cstring> 6 #include <algorithm> 7 8 using namespace std; 9 const int N = 105; 10 const int INF = 0x3f3f3f3f; 11 12 int k , fa[N] , minn[N] , first[N] , vis[N];//vis[N]表示是否添入以保存的集合 13 14 struct Edge{ 15 int y , next , d; 16 bool operator<(const Edge & m )const{ 17 return d < m.d; 18 } 19 }e[N*N]; 20 21 void add_edge(int x , int y, int d) 22 { 23 e[k].y = y , e[k].next = first[x] , e[k].d = d; 24 first[x] = k++; 25 } 26 27 int prim(int src , int n) 28 { 29 memset(minn , 0x3f , sizeof(minn)); 30 memset(vis , 0 , sizeof(vis)); 31 vis[src] = 1; 32 for(int i = first[src] ; i!=-1 ; i=e[i].next) 33 { 34 int v = e[i].y; 35 if(!vis[v]) minn[v] = min(minn[v] , e[i].d); 36 } 37 int ans = 0; 38 for(int i = 1 ; i<n ; i++) 39 { 40 int index = 0 , Min = INF; 41 for(int j = 1 ; j<=n ; j++) 42 { 43 if(minn[j] < Min){ 44 Min = minn[j]; 45 index = j; 46 } 47 } 48 ans += Min; 49 minn[index] = INF; 50 vis[index] = 1; //使index不能再被访问 51 //更新 52 for(int j = first[index] ; j!=-1 ; j=e[j].next) 53 { 54 int v = e[j].y; 55 if(!vis[v]) minn[v] = min(minn[v] , e[j].d); 56 } 57 } 58 return ans; 59 } 60 61 int main() 62 { 63 // freopen("a.in" , "r" , stdin); 64 int n , m , a , b , d; 65 while(scanf("%d" , &n) , n) 66 { 67 m = n*(n-1) / 2; 68 for(int i = 1 ; i<=n ; i++) fa[i] = i; 69 70 k = 0; 71 memset(first , -1 , sizeof(first)); 72 for(int i = 0 ; i<m ; i++){ 73 scanf("%d%d%d" , &a , &b , &d); 74 add_edge(a , b , d); 75 add_edge(b , a , d); 76 } 77 78 printf("%d " , prim(1 , n)); 79 } 80 return 0; 81 }
kruscal:
1 /* 2 最小生成树,prim算法 3 */ 4 #include <cstdio> 5 #include <cstring> 6 #include <algorithm> 7 8 using namespace std; 9 const int N = 105; 10 11 int k , fa[N]; 12 13 struct Edge{ 14 int x , y , d; 15 bool operator<(const Edge & m )const{ 16 return d < m.d; 17 } 18 }e[N*N]; 19 20 void add_edge(int x , int y, int d) 21 { 22 e[k].x = x , e[k].y = y , e[k].d = d; 23 k++; 24 } 25 26 int get_head(int x) 27 { 28 while(x != fa[x]) x=fa[x]; 29 return x; 30 } 31 32 bool Union(int x , int y) 33 { 34 int fa_x = get_head(x); 35 int fa_y = get_head(y); 36 if(fa_x != fa_y){ 37 fa[fa_x] = fa_y; 38 return true; 39 } 40 return false; 41 } 42 43 int main() 44 { 45 // freopen("a.in" , "r" , stdin); 46 int n , m , a , b , d; 47 while(scanf("%d" , &n) , n) 48 { 49 k = 0; 50 m = n*(n-1) / 2; 51 52 for(int i = 1 ; i<=n ; i++) fa[i] = i; 53 54 for(int i = 0 ; i<m ; i++){ 55 scanf("%d%d%d" , &a , &b , &d); 56 add_edge(a , b , d); 57 } 58 sort(e , e+k); 59 int ans = 0; 60 for(int i = 0 ; i<k ; i++){ 61 if(Union(e[i].x , e[i].y)) ans += e[i].d; 62 } 63 printf("%d " , ans); 64 } 65 return 0; 66 }