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。

posted @ 2012-08-21 08:49  pushing my way  阅读(213)  评论(0编辑  收藏  举报