zoukankan      html  css  js  c++  java
  • 5-10 公路村村通 (30分)

    5-10 公路村村通   (30分)

    现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本。

    输入格式:

    输入数据包括城镇数目正整数NN(le 10001000)和候选道路数目MM(le 3N3N);随后的MM行对应MM条道路,每行给出3个正整数,分别是该条道路直接连通的两个城镇的编号以及该道路改建的预算成本。为简单起见,城镇从1到NN编号。

    输出格式:

    输出村村通需要的最低成本。如果输入数据不足以保证畅通,则输出-11,表示需要建设更多公路。

    输入样例:

    6 15
    1 2 5
    1 3 3
    1 4 7
    1 5 4
    1 6 2
    2 3 4
    2 4 6
    2 5 2
    2 6 6
    3 4 6
    3 5 1
    3 6 1
    4 5 10
    4 6 8
    5 6 3
    

    输出样例:

    12

    ----------分析-----------------------------
    这是一个典型的最小生成树的问题。当时去厦大夏令营面试的时候遇到这个问题,我束手无策。今天下午花了一个下午+晚上的时候才算搞清楚了些Prime算法。
    算法的思路可自行百度。这里贴出我写的代码
      1 #include <stdio.h>
      2 #define MAX_VEX_NUM 101
      3 #define MAX_VALUE 9999
      4 
      5 typedef struct Graph
      6 {
      7     int vex[MAX_VEX_NUM][MAX_VEX_NUM];
      8     int vexNum;
      9     int arsNum;
     10 }Graph;
     11 
     12 
     13 struct closedeg
     14 {
     15     int vex;
     16     int lowcost;
     17 } closedeg[MAX_VEX_NUM];
     18  
     19 void init(Graph *G)
     20 {
     21     int i, j;
     22     for(i = 1; i <= G->vexNum; i++)
     23         for(j = 1; j <= G->vexNum; j++)
     24             G->vex[i][j] = MAX_VALUE;
     25 }
     26 
     27 int isLianTong(Graph *G)
     28 {
     29     int i, j, flag = 0;
     30     for(i = 1; i <= G->vexNum; i++)
     31     {
     32         for(j = 1; j <= G->vexNum; j++)
     33         {
     34             if(G->vex[i][j] != MAX_VALUE)
     35             {
     36                 flag ++;
     37                 break;
     38             }    
     39         }    
     40     }
     41     if(flag < G->vexNum)
     42         return 0;
     43     else
     44         return 1;
     45 }
     46 
     47 void print(Graph *G)
     48 {
     49     int i, j;
     50     for(i = 1; i <= G->vexNum; i++)
     51     {
     52         for(j = 1; j <= G->vexNum; j++)
     53             printf("%d ", G->vex[i][j]);
     54         printf("
    ");
     55     }
     56 }
     57 
     58 int Min(Graph *G, struct closedeg cld[])
     59 {
     60     int i, min = MAX_VALUE, min_index = 2;
     61     for(i = 2; i <= G->vexNum; i++)
     62     {
     63         if(cld[i].lowcost != 0)
     64         {
     65             if(min > cld[i].lowcost)
     66             {
     67                 min = cld[i].lowcost;
     68                 min_index = i;
     69             }
     70         }
     71     }
     72     return min_index;
     73 }
     74 
     75 void Prim(Graph *G, int v)
     76 {
     77     int i, e;
     78     int k0, u0, v0;
     79     int sum = 0;
     80     closedeg[v].lowcost = 0;
     81     for(i = 1; i <= G->vexNum; i++) //对V-U中的点进行初始化closedeg[]
     82     {
     83         if(i != v)
     84         {
     85             closedeg[i].vex = v;
     86             closedeg[i].lowcost = G->vex[v][i];
     87         }
     88     }
     89 
     90     for(e = 1; e <= G->vexNum - 1; e++)  //找到n-1条边
     91     {
     92 
     93         k0 = Min(G, closedeg);
     94         u0 = closedeg[k0].vex; //最小边的点左端点
     95         v0 = k0;  //最小边的点右端点
     96         // printf("(%d, %d) 
    ", u0, v0);;  //输出最小边
     97         sum += G->vex[u0][v0];
     98         closedeg[k0].lowcost = 0;
     99         for(i = 2; i <= G->vexNum; i++)
    100         {
    101             if(G->vex[k0][i] < closedeg[i].lowcost)
    102             {
    103                 closedeg[i].lowcost = G->vex[k0][i];
    104                 closedeg[i].vex = v0;
    105             }
    106         }
    107     }
    108     if(1 ==  isLianTong(G))
    109         printf("%d
    ", sum);
    110     else
    111         printf("-1
    ");
    112 }
    113 
    114 void creat(Graph *G)
    115 {
    116     int i;
    117     // FILE *fp;
    118     // fp = fopen("input.txt", "r");
    119     scanf("%d %d", &G->vexNum, &G->arsNum);
    120     // fscanf(fp, "%d %d", &G->vexNum, &G->arsNum);
    121     init(G);
    122     for(i = 1; i <= G->arsNum; i++)
    123     {
    124         int ars1, ars2, weight;
    125         scanf("%d %d %d", &ars1, &ars2, &weight);
    126         // fscanf(fp, "%d %d %d", &ars1, &ars2, &weight);
    127         G->vex[ars1][ars2] = weight;
    128         G->vex[ars2][ars1] = weight;
    129     }
    130     // print(G);
    131 }
    132 
    133 int main()
    134 {
    135     Graph G;
    136     creat(&G);
    137     Prim(&G, 1);
    138     return 0;
    139 }

    这里面有很多函数是这个题目所不需要的。因为我在写这个程序的时候并不是一帆风顺的,中间遇到过很多问题。所以保留了一些我改动的痕迹。

    只可惜最后上传的时候只能拿22分,剩下还有两个测试点,我也不知道哪个地方出了问题。

  • 相关阅读:
    matlab二维绘图学习摘要
    linux下有名管道进程通信
    《编写可读代码的艺术》第10章 抽取不相关的子问题
    《编写可读代码的艺术》第9章 变量可读性
    《编写可读代码的艺术》第8章 拆分超长的表达式
    《编写可读代码的艺术》第7章 简化循环和逻辑
    《编写可读代码的艺术》第6章 写出言简意赅的注释
    《编写可读代码的艺术》第5章 该写什么样的注释
    《编写可读代码的艺术》第4章 审美
    《编写可读代码的艺术》第3章 不会误解的名字
  • 原文地址:https://www.cnblogs.com/hello-lijj/p/7341163.html
Copyright © 2011-2022 走看看