• 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]……唉,程序本身原来就是错的。又是这种细节,,这些中间变量最容易错了。从现在开始,要特别小心。敲代码一定要认真。老是出这种错误,也许这就是为什么我效率这么低的原因。。唉……

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

  • 相关阅读:
    LeetCode OJ-- Interleaving String **@
    二叉树遍历 Morris
    LeetCode OJ--Binary Tree Zigzag Level Order Traversal *
    LeetCode OJ-- Letter Combinations of a Phone Number ***
    【转】 堆和栈的区别
    LeetCode OJ-- Valid Sudoku
    LeetCode OJ--Word Break II ***@
    LeetCode OJ-- Surrounded Regions **@
    add host bat
    SP2013 SP1(kb28805502)补丁安装测试初体验
  • 原文地址:https://www.cnblogs.com/liuxueyang/p/3056837.html
Copyright © 2020-2023  润新知