poj1789 Truck History ——最小生成树入门题_Prim算法

题目链接:http://poj.org/problem?id=1789

题目大意:

  输入一个数字n,然后输入n个长度为7的字符串,从任意一个字符串开始派生,直到派生出所有的字符串,两个字符串的距离规定为他们对应位置不相等的字母的个数,求出一种派生方案,使得派生方案的优劣值最大,并输出这个优劣值。优劣值的定义是:1/Σ(to,td)d(to,td) 表示对所有派生对的距离求和,再取倒数。

题目了思路:

  要让优劣值最大,只需要距离之和最小,把7个字符串看成7个点,每两个点有一个距离,目的就是求权值最小的生成树,其实就是最小生成树。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <cctype>
 6 #include <stack>
 7 #include <queue>
 8 #include <map>
 9 #include <set>
10 #include <vector>
11 #include <cmath>
12 #include <algorithm>
13 #define lson l, m, rt<<1
14 #define rson m+1, r, rt<<1|1
15 using namespace std;
16 typedef long long int LL;
17 const int MAXN =  0x3f3f3f3f;
18 const int  MIN =  -0x3f3f3f3f;
19 const double eps = 1e-9;
20 const int dir[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1},
21   {1,1},{1,-1},{-1,-1}};
22 const int MAX = 2000+10;
23 char a[MAX][MAX];
24 int edge[MAX][MAX];
25 int n, lowcost[MAX];
26 void prim(int u0) 
27 {
28   int sum = 0, i, j, k;
29   for (i = 1; i <= n; ++i) lowcost[i] = edge[u0][i];
30   lowcost[u0] = -1;
31   for (i = 1; i < n; ++i) {
32     int v = -1, min = MAXN;
33     for (j = 1; j <= n; ++j) {
34       if (lowcost[j] != -1 && min > lowcost[j]) {
35         min = lowcost[j]; v = j;
36       }
37     }
38     if (v != -1) 
39     {
40       sum += lowcost[v]; lowcost[v] = -1;
41       for (j = 1; j <=n; ++j) {
42         if (edge[v][j] < lowcost[j]) {
43           lowcost[j] =edge[v][j];
44         }
45       }
46     }
47   }
48   printf("The highest possible quality is 1/%d.\n", sum);
49 }
50 int main(void){
51 #ifndef ONLINE_JUDGE
52   freopen("zoj2158.in", "r", stdin);
53 #endif
54   int i, j, k;
55  while (~scanf("%d", &n) && n) {
56     memset(edge, 0, sizeof(edge)); memset(lowcost, 0, sizeof(lowcost));
57     for (i = 1; i <= n; ++i)
58       scanf("%s", a[i]);
59     int cnt;
60     for (i = 1; i <= n; ++i) {
61       for (j = i+1; j <= n; ++j) {
62         cnt = 0;
63         for (k = 0; k < 7; ++k) {
64           if (a[i][k] != a[j][k]) cnt++;
65         }
66         edge[i][j] = edge[j][i] = cnt;
67       }
68     }
69     prim(1);
70   }
71 
72   return 0;
73 }

  写的过程中,依然是WA了好多次,样例是过了,但是程序就是不知道哪里错了。后来自己出了组数据,才发现了错误,原来prim过程里面的一个 lowcost[j] 写成了 lowcost[v]……唉,程序本身原来就是错的。又是这种细节,,这些中间变量最容易错了。从现在开始,要特别小心。敲代码一定要认真。老是出这种错误,也许这就是为什么我效率这么低的原因。。唉……

  另外就是,程序出错了之后,自己耐心地出有效的数据也是一种能力。

posted on 2013-05-03 16:00  aries__liu  阅读(186)  评论(0编辑  收藏  举报