hdu 3371 最小生成树

深夜来一发,裸的最小生成树,数据量还挺大,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 }
View Code

prim算法:

 

你可能感兴趣的:(最小生成树)