1813:还是畅通工程

时间限制:1 秒
内存限制:32 兆
特殊判题: 否
提交:94
解决: 43

标签

  • 最小生成树

题目描述

 

        某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。

 

输入格式

 

        测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。
        当N为0时,输入结束,该用例不被处理。

 

输出

 

        对每个测试用例,在1行里输出最小的公路总长度。

 

样例输入

8
1 2 42
1 3 68
1 4 35
1 5 1
1 6 70
1 7 25
1 8 79
2 3 59
2 4 63
2 5 65
2 6 6
2 7 46
2 8 82
3 4 28
3 5 62
3 6 92
3 7 96
3 8 43
4 5 28
4 6 37
4 7 92
4 8 5
5 6 3
5 7 54
5 8 93
6 7 83
6 8 22
7 8 17
0

样例输出

82

稠密图,prim算法:
 1 #include <stdio.h>

 2 #define INF 500000 

 3 typedef struct

 4 {

 5     int eage[101][101];

 6     

 7 }GRAPH;

 8 GRAPH g;

 9 int main(Void)

10 {

11     //freopen("in.txt","r",stdin);

12     int n;

13     while(scanf("%d",&n)!=EOF&&n!=0)

14     {

15         int e;

16         e=n*(n-1)/2;

17         int i;

18         int a,b,w;

19         for(i=0;i<n;i++)

20         {

21             int j;

22             for(j=1;j<=n;j++)

23                 g.eage[i][j]=INF;

24         }

25         for(i=1;i<=e;i++)

26         {

27             scanf("%d %d %d",&a,&b,&w); 

28             g.eage[a][b]=w;

29             g.eage[b][a]=w;

30             

31         }

32         int lowcost[5000];

33         int vset[5000];

34         for(i=1;i<=n;i++)

35         {

36             lowcost[i]=g.eage[1][i];

37             

38             vset[i]=0;

39         }

40         vset[1]=1;

41         int sum=0;

42         int u;

43     

44     

45         for(i=1;i<n;i++)//已经排除掉初始点,还剩下n-1次选择 

46         {    

47             int min=INF;

48             int j;

49             for(j=1;j<=n;j++)

50             {

51                 if(vset[j]==0&&lowcost[j]<min)

52                 {

53                     min=lowcost[j];

54                     u=j;

55                 }

56             

57             }

58         

59             vset[u]=1;

60             sum+=min;

61             int k;

62             for(k=1;k<=n;++k)

63             {

64                 if(vset[k]==0&&g.eage[u][k]<lowcost[k])

65                     lowcost[k]=g.eage[u][k];

66             }

67         }

68         printf("%d\n",sum);

69     }

70     return 0;

71     

72 }

Kruskal算法:

 1 #include <stdio.h> 

 2 typedef struct

 3 {

 4     int a;

 5     int b;

 6     int w;

 7 }ROAD;

 8 ROAD road[5000];

 9 int v[5000];

10 int getroot(int m)

11 {

12     

13     while(m!=v[m])

14         m=v[m];

15     return m;

16 }

17 int main(void)

18 {

19     //freopen("in.txt","r",stdin);

20     int n;

21     int e;

22     while(scanf("%d",&n)!=EOF&&n!=0)

23     {

24         int sum=0;

25         e=n*(n-1)/2;

26         int i;

27         for(i=0;i<e;i++)

28         {

29             scanf("%d %d %d",&road[i].a,&road[i].b,&road[i].w);

30             //printf("%d %d %d\n",road[i].a,road[i].b,road[i].w);

31         }

32         for(i=1;i<=n;i++)

33             v[i]=i;

34         for(i=e-1;i>0;i--)

35         {

36             int j;

37             ROAD tmp;

38             for(j=0;j<i;j++) 

39                 if(road[j].w>road[j+1].w)

40                     {

41                         tmp=road[j];

42                         road[j]=road[j+1];

43                         road[j+1]=tmp;

44                         

45                     }

46         }

47         for(i=0;i<e;i++)

48         {

49             int a,b;

50             a=getroot(road[i].a);

51             b=getroot(road[i].b);

52             if(a!=b)

53             {

54                 v[a]=b;

55                 sum+=road[i].w;

56             }

57         }

58         printf("%d\n",sum);

59     }

60     return 0;

61 }

 prim耗时少很多

你可能感兴趣的:(1813:还是畅通工程)