专题四1004

来源:互联网 发布:淘宝我要日报在哪 编辑:程序博客网 时间:2024/05/17 20:33

题目大意:

谋生的统计表中列出了任意两个村庄见的距离,为了实现全省两个村庄间都可以实现公路交通,现在要修路,要求编程输出在满足任意两个村庄都是可达的前提下,需要修建的最短的公路长度。

输入:

测试实例包括多个。每个实例的第一行输入一个正整数N,代表村庄的数目,然后接下来的m=N*N-1/2行每行包括3个整数,前两个整数代表两个村庄的编号,然后第3个整数代表两个村庄的距离。当输入的N0时,程序结束。

输出:

每行输出一个整数,代表每个实例的结果。

解题思路:

并查集问题。首先定义一个结构体变量Road,属性包括两个村庄的编号以及这两个村庄见的距离,定义一个Road类型的数组road[110],题目要求输出最短路径,输入信息完毕后,将所有路径按照路径长度从小到大的顺序排列起来,用一个整形数组P[100]存储节点,并初始化,代表刚开始时各个节点之间没有关联,然后一个for循环,从1m,对于每条路径进行合并,若findx(x)==findx(y),说明两个节点之前已经联通;若findx(x)!=findx(y),说明两个节点之间无关联,此时加上这两个节点间的距离,然后将这两个节点合并,代表两个节点间现已联通,最后得到的totallength即为答案,因为我们事先已经把路径按照从小到大的顺序排列,所以这样得到的答案一定是最短的。

感想:

关于图的问题感觉并不难,其实说白了就是一个并查集的使用,只是现在感觉到图这个东西真的太重要了,好几门学科都涉及到了图。

代码如下:

#include<iostream>

#include<algorithm>

using namespace std;

struct Road

{

int x;

int y;

int length;

};

Road road[200];

int p[100];

int TotalLength;

bool Judge(Road &r1, Road &r2)

{

return r1.length < r2.length;

}

int findx(int x)

{

int r = x;

if (p[x] == r)

return r;

else

return findx(p[x]);

}

void merge(int x, int y,int z)

{

int fx, fy;

fx = findx(x);

fy = findx(y);

if (fx != fy)

{

p[fx] = fy;

TotalLength += road[z].length;

}

}

int main()

{

int n, m;

while (cin >> n)

{

TotalLength = 0;

if (n == 0)

break;

m = n*(n - 1) / 2;

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

p[i] = i;

for (int i = 1; i <= m; i++)

cin >> road[i].x >> road[i].y >> road[i].length;

sort(road + 1, road + 1 + m, Judge);

for (int i = 1; i <= m; i++)

merge(road[i].x, road[i].y, i);

cout << TotalLength << endl;

}

return 0;

}

 

0 0