zoukankan      html  css  js  c++  java
  • POJ-1789-Truck History 解题报告

           一道求最小生成树的水题,数据十分水,属于稠密图,适合用prim算法,不过本人还是用的kruskal算法(表示目前还不会prim算法)。题意:以一个由七位小写字母组成的字符串为车辆编号,每辆车的编号只能由另一辆车的编号衍生出来(第一辆车不算),衍生的代价为编号中对应位字母不相同的个数。比如aaaaaaa与baaaaaa有一个位的字母不相同,因此它们互相衍生出来的代价是1。又比如在baaaaaa与abaaaaa有两个对应位的字母不同,因此它们互相衍生的代价是2。在样例中,很明显当第二,三,四辆车的编号都由第一辆车编号衍生出来时代价最小,分别为1,1,1。因此总代价为3。题目要求求出这些车辆编号的最小衍生总代价,就是求它们的最小生成树。


           题目数据比较水,初步估计没有当N=2000的极限数据。这道题一直错,我查错查了很久,最后发现原来是没有做多组输入中当输入N=0时结束程序的特殊判断(囧),还是不够细心……


           下面是我的解题代码

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #define N 2010
      4 #define M 10
      5 
      6 typedef struct side     /*定义边的结构体*/
      7 {
      8     int a, b;   /*两点的下标*/
      9     int len;    /*边长*/
     10 }side;
     11 
     12 side s[N*N];
     13 int bleg[N];        /*并查集使用,存储父节点*/
     14 char type[N][M];
     15 int ans;
     16 int n;
     17 int sn;     /*边的数量*/
     18 
     19 void Init();        /*初始化*/
     20 
     21 void Read();        /*输入点并且计算边*/
     22 
     23 int Mycmp(const void *a, const void *b);
     24 
     25 void Link();        /*连接边构成最小生成树*/
     26 
     27 int Count(int x, int y);        /*计算边长*/
     28 
     29 int Find(int x);        /*查找*/
     30 
     31 void Union(int x, int y, int i);        /*合并,根据题目增加特殊操作*/
     32 
     33 int main()
     34 {
     35     while (~scanf("%d", &n))
     36     {
     37         if (n == 0) break;      /*忘了写这个,一直WA(囧)*/
     38         Init();
     39         Read();
     40         qsort(s, sn, sizeof(side), Mycmp);
     41         Link();
     42     }
     43     return 0;
     44 }
     45 
     46 void Init()     /*初始化*/
     47 {
     48     int i;
     49     ans = 0;
     50     sn = 0;
     51     for (i=0; i<N; i++)
     52     {
     53         bleg[i] = i;
     54     }
     55     return;
     56 }
     57 
     58 void Read()     /*输入点并且计算边*/
     59 {
     60     int i, j;
     61     for (i=0; i<n; i++)
     62     {
     63         scanf("%s", type[i]);
     64         for (j=0; j<i; j++)     /*计算新增加的边*/
     65         {
     66             s[sn].a = i;
     67             s[sn].b = j;
     68             s[sn++].len = Count(i, j);
     69         }
     70     }
     71     return;
     72 }
     73 
     74 int Count(int x, int y)     /*计算边长*/
     75 {
     76     int i;
     77     int num = 0;
     78     for (i=0; i<7; i++)
     79     {
     80         if (type[x][i] != type[y][i])
     81         {
     82             num++;
     83         }
     84     }
     85     return num;
     86 }
     87 
     88 int Mycmp(const void *a, const void *b)
     89 {
     90     return (*(side *)a).len - (*(side *)b).len;
     91 }
     92 
     93 void Link()         /*连接边构成最小生成树*/
     94 {
     95     int i;
     96     for (i=0; i<sn; i++)
     97     {
     98         Union(s[i].a, s[i].b, i);
     99     }
    100     printf("The highest possible quality is 1/%d.
    ", ans);
    101     return;
    102 }
    103 
    104 int Find(int x)     /*查找*/
    105 {
    106     int y = bleg[x];
    107     int z;
    108     while (y != bleg[y])
    109     {
    110         y = bleg[y];
    111     }
    112     while (x != bleg[x])
    113     {
    114         z = bleg[x];
    115         bleg[x] = y;
    116         x = z;
    117     }
    118     return y;
    119 }
    120 
    121 void Union(int x, int y, int i)     /*合并,根据题目增加特殊操作*/
    122 {
    123     int fx = Find(x);
    124     int fy = Find(y);
    125     if (fx == fy) return;
    126     ans += s[i].len;        /*计算最小生成树的边长*/
    127     bleg[fx] = fy;
    128     return;
    129 }
  • 相关阅读:
    完美解决 向UILable 文字最后插入N张图片,支持向限制行数的UILable 最后一行插入,多余文字显示...
    构建自己的NSZombie
    如何以代码形式插入断点
    根据坐标点显示地图显示范围(高德地图)
    ios7 UITableView 分割线在 使用selectedBackgroundView 选中时有些不显示
    runtime MethodSwizzle 实践之 奇怪crash : [UIKeyboardLayoutStar release]: message sent to deallocated instance
    Jmeter(十一)
    Jmeter(十)
    Jmeter(九)
    Jmeter(八)
  • 原文地址:https://www.cnblogs.com/JZQT/p/3802449.html
Copyright © 2011-2022 走看看