1251 Jungle Roads 解题报告

来源:互联网 发布:无需网络的手机游戏大全 编辑:程序博客网 时间:2024/06/06 08:46

AccecptTime:          2008-12-18 12:04:07 2008-12-18 12:24:03
Language:                 c++
Memory:                  292K 292K
Time:                       0 MS
Errors:                      3 RE
Algorithm:               最小生成树 Kruskal + Prim

 

 

    1. //这段代码用的是Kruskal算法,用到了并查集
    2. #include <stdio.h>
    3. #include <stdlib.h>
    4. #include <memory.h>
    5. #include <iostream>
    6. using namespace std;
    7. typedef struct Edge{
    8.     int x;
    9.     int y;
    10.     int weigh;
    11. }Edge;
    12. Edge edge[1000];
    13. int parent[100];
    14. //寻找父节点
    15. int FindParent(int x)
    16. {
    17.     if(parent[x])
    18.         parent[x] = FindParent(parent[x]);
    19.     else
    20.         return x;
    21.     return parent[x];
    22. }
    23. //并查集合并
    24. void MergeSet(int x, int y)
    25. {
    26.     int t1 = FindParent(x);
    27.     int t2 = FindParent(y);
    28.     if( t1 > t2)
    29.         parent[t2] = t1;
    30.     else
    31.         parent[t1] = t2;
    32. }
    33. //用于qsort()的比较函数
    34. int compare(const void* a,const void* b)
    35. {
    36.     return ((Edge*)a)->weigh - ((Edge*)b)->weigh;
    37. }
    38. int main()
    39. {
    40.     int n, count;
    41.     char x,y;
    42.     int v, weigh, sum;
    43.     cin >> n;
    44.     while( n) {
    45.         getchar();
    46.         count = sum = 0;
    47.         forint i = 0; i < n - 1; i++) {
    48.             cin >> x >> v;
    49.             x = x - 'A' + 1;
    50.             forint j = 0; j < v; j++) {
    51.                 cin >> y >>weigh;
    52.                 y = y - 'A' + 1;
    53.                 edge[count].x = x;
    54.                 edge[count].y = y;
    55.                 edge[count++].weigh = weigh;
    56.             }
    57.             getchar();
    58.         }
    59.         qsort(edge,count,sizeof(Edge),compare);
    60.         //对并查集进行初始化
    61.         memset(parent,0,27 * sizeof(int));
    62.         for(int i = 0; i < count; i++)
    63.             //判断两个节点是否在同一个集合
    64.             if(FindParent(edge[i].x) != FindParent(edge[i].y)) {
    65.                 sum += edge[i].weigh;
    66.                 MergeSet(edge[i].x,edge[i].y);
    67.             }
    68.         cout << sum << endl;
    69.         cin >> n;
    70.     }
    71. }
    //这用的是Prim算法
  1. #include <iostream>
  2. using namespace std;
  3. //记录集合的元素
  4. int in[26];
  5. //路径储存
  6. int road[26][26];
  7. //记录是否在集合内
  8. int inv[26];
  9. int main()
  10. {
  11.     int n, v, weigh;
  12.     int min,mink,j;
  13.     char x, y;
  14.     cin >> n;
  15.     while(n) {
  16.         int sum = 0;
  17.         forint i = 0; i < 26; i++)
  18.             forint j = 0; j < 26; j++)
  19.                 road[i][j] = 0;
  20.         memset(inv,0,26 * sizeof(int));
  21.         forint i = 0; i < n - 1; i++) {
  22.             cin >> x >> v;
  23.             x -= 'A';
  24.             forint j = 0; j < v; j++) {
  25.                 cin >> y >> weigh;
  26.                 y -= 'A';
  27.                 road[x][y] = road[y][x] = weigh;
  28.             }
  29.         }
  30.         in[0] = 0;
  31.         inv[0] = 1;
  32.         forint i = 1; i < n; i++) {
  33.             min = 99999999;
  34.             for(j = 0; j < i; j++)
  35.                 forint k = 0; k < n; k++)
  36.                     // 先判断节点是否已经加入,再判断路径是否存在,再判断路径是否最小
  37.                     if(!inv[k] && road[(in[j])][k] && road[(in[j])][k] < min) {
  38.                         min = road[in[j]][k];
  39.                         mink = k;
  40.                     }
  41.             //将mink点加入集合,并标记
  42.             in[j] = mink;
  43.             inv[mink] = 1;
  44.             sum += min;
  45.         }
  46.         cout << sum << endl;
  47.         cin >> n;
  48.     }
  49. }

这道题考察的是最小生成树,我分别用Kruskal 和 Prim 解出,发现内存使用和时间都是一样,但是一向低效的Prim只用了Kruskal一半多的代码(囧..),另外这道题输入很bt(在行尾会有多余空格),导致了3 RE,下次能用cin的时候要用cin。这题写得有点慢..下次遇见的时候应该直接秒杀~~