poj1789_最小生成树

这个最小生成树的题比较简单,但是需要注意:

Kruskal不适合稠密图中,这个题是稠密图,用kruskal800+ms,而prim400ms.

还有cin和scanf的耗时差距好大啊。

prim代码:

View Code
 1 #include <iostream>

 2 #include <stdio.h>

 3 using namespace std;

 4 //454ms

 5 const int maxnum=2001;

 6 const int maxdigit=(1<<30);

 7 int array[maxnum][maxnum];

 8 int close[maxnum];

 9 int use[maxnum];

10 int n;

11 

12 int prim(int u)

13 {

14     int i,k;

15     for(i=0;i<n;i++)

16     {

17         close[i]=array[u][i];

18         use[i]=false;

19     }

20     use[u]=true;

21     int temp,t;

22     int sum=0;

23     for(k=0;k<n-1;k++)

24     {

25         temp=maxdigit+5;

26         for(i=0;i<n;i++)

27             if(!use[i] && close[i]<temp)

28             {

29                 temp=close[i];

30                 t=i;

31             }

32         use[t]=true;

33         sum+=close[t];

34         for(i=0;i<n;i++)

35             if(!use[i] && array[t][i]<close[i])

36                 close[i]=array[t][i];

37     }

38     return sum;

39 }

40 

41 int main()

42 {

43     int i,j,k,w;

44     char str[maxnum][7];

45     while(scanf("%d",&n) && n!=0)

46     {

47         for(i=0;i<n;i++)

48             scanf("%s",str[i]);

49         for(i=0;i<n;i++)

50             for(j=0;j<n;j++)

51                 array[i][j]=maxdigit;

52         for(i=0;i<n;i++)

53             for(j=i+1;j<n;j++)

54             {

55                 w=0;

56                 for(k=0;k<7;k++)

57                     if(str[i][k]!=str[j][k])

58                         w++;

59                 array[i][j]=array[j][i]=w;

60             }

61         printf("The highest possible quality is 1/%d.\n",prim(0));

62     }

63     return 0;

64 }

65 

66 /*

67 4

68 aaaaaaa

69 baaaaaa

70 abaaaaa

71 aabaaaa

72 */

kruskal代码:

View Code
 1 #include <iostream>

 2 #include <stdio.h>

 3 #include <string>

 4 #include <algorithm>

 5 using namespace std;

 6 //22944K 860MS

 7 //稠密图用kruskal很费时啊!

 8 const int maxnum=2000000;

 9 struct edge

10 {

11     int s,e;

12     int w;

13 }edge[maxnum];

14 int parent[2001];

15 int rank[2001];

16 

17 bool cmp(struct edge a,struct edge b)

18 {

19     return a.w<b.w;

20 }

21 

22 int find(int i)

23 {

24     if(i!=parent[i])

25         parent[i]=find(parent[i]);

26     return parent[i];

27 }

28 

29 void Union(int i,int j)

30 {

31     if(rank[i]<rank[j])

32         parent[i]=j;

33     else

34     {

35         parent[j]=i;

36         if(rank[i]==rank[j])

37             i++;

38     }

39 }

40 

41 int main()

42 {

43     string str[2001];

44     int num,i,j,k,w;

45     int index,sum;

46     while(scanf("%d",&num) && num!=0)

47     {

48         for(i=0;i<num;i++)

49             cin>>str[i];

50         index=0;

51         for(i=0;i<num;i++)

52             for(j=i+1;j<num;j++)

53             {

54                 w=0;

55                 for(k=0;k<7;k++)

56                     if(str[i][k]!=str[j][k])

57                         w++;

58                     edge[index].s=i;

59                     edge[index].e=j;

60                     edge[index].w=w;

61                     index++;

62             }

63         sort(edge,edge+index,cmp);

64 

65         sum=0;

66         for(i=0;i<num;i++)

67         {

68             parent[i]=i;

69             rank[i]=0;

70         }

71         for(i=0;i<index;i++)

72         {

73             int a=find(edge[i].s);

74             int b=find(edge[i].e);

75             if(a!=b)

76             {

77                 Union(a,b);

78                 sum+=edge[i].w;

79             }

80         }

81         printf("The highest possible quality is 1/%d.\n",sum);

82     }

83     return 0;

84 }

85 

86 /*

87 4

88 aaaaaaa

89 baaaaaa

90 abaaaaa

91 aabaaaa

92 */

93 /*

94 为什么在main里面定义map[2000][2000]时候VC就超内存,

95 而定义在main外面就行了呢?

96 ans:

97 定义在main()里面就是用的栈空间啊,一般会报stack overflow的错误,

98 定义在外面用的就是全局数据区了

99 */

tju oj2267
类似还有 poj1251。

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