标签:
深夜来一发,裸的最小生成树,数据量还挺大,kruskal算法g++始终过不去,c++刚好飘过,这个时候就体现出kruskal和prim的适用范围的不同了,前者适用于稀疏图,后者适用于稠密图。
kruskal算法:
1 #include <stdio.h> 2 #include <algorithm> 3 using namespace std; 4 5 const int N = 501; 6 const int M = 25000; 7 int f[N]; 8 int buffer[N]; 9 int n, m, k, e; 10 11 void init() 12 { 13 e = 0; 14 for ( int i = 1; i <= n; i++ ) f[i] = i; 15 } 16 17 int find_f( int x ) 18 { 19 if ( f[x] != x ) f[x] = find_f(f[x]); 20 return f[x]; 21 } 22 23 bool union_set( int x, int y ) 24 { 25 x = find_f(x), y = find_f(y); 26 if ( x != y ) 27 { 28 f[x] = y; 29 return true; 30 } 31 return false; 32 } 33 34 struct Edge 35 { 36 int u, v, w; 37 } edge[M]; 38 39 bool cmp( Edge a, Edge b ) 40 { 41 return a.w < b.w; 42 } 43 44 int main () 45 { 46 int t; 47 scanf("%d", &t); 48 while ( t-- ) 49 { 50 scanf("%d%d%d", &n, &m, &k); 51 init(); 52 while ( m-- ) 53 { 54 scanf("%d%d%d", &edge[e].u, &edge[e].v, &edge[e].w); 55 e++; 56 } 57 int cnt = 0; 58 while ( k-- ) 59 { 60 int tmp; 61 scanf("%d", &tmp); 62 for ( int i = 0; i < tmp; i++ ) 63 { 64 scanf("%d", buffer + i); 65 } 66 for ( int i = 0; i < tmp - 1; i++ ) 67 { 68 if ( union_set( buffer[i], buffer[i + 1] ) ) 69 { 70 cnt++; 71 } 72 } 73 } 74 if ( cnt == n - 1 ) 75 { 76 printf("0\n"); 77 continue; 78 } 79 int sum = 0; 80 sort( edge, edge + e, cmp ); 81 for ( int i = 0; i < e; i++ ) 82 { 83 if ( union_set( edge[i].u, edge[i].v ) ) 84 { 85 sum += edge[i].w; 86 cnt++; 87 if ( cnt == n - 1 ) break; 88 } 89 } 90 if ( cnt == n - 1 ) printf("%d\n", sum); 91 else printf("-1\n"); 92 } 93 return 0; 94 }
prim算法:
标签:
原文地址:http://www.cnblogs.com/huoxiayu/p/4395170.html