4最短路径之村庄4

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

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

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

Sample Input

3 1 2 1 1 3 2 2 3 4 4 1 2 1 1 3 4 1 4 1 2 3 3 2 4 2 3 4 5 0
 

Sample Output

3 5
题目大意:首先给出村庄的数目n,然后下面n行分别给出村庄节点以及两个村庄之间的距离。要求找出这些村庄之间的最短路径。
思路:Kruscal算法。首先把所有的道路看成一个整体包含三个性质,两头的节点以及权值。建立道路集合,并且根据村庄之间的权值大小进行排序。然后挑选路径,大的方向是从小到大,条件是道路两旁的节点不能在一个集合之中,所以根据并查集合并节点。挑选这条道路的两个条件就此形成:1,短。2,两头的节点不能在同一个集合之中。
代码:
#include #include #include #include using namespace std; typedef struct rode {     int c1,c2,cost;//建立道路,包括两头的村庄以及道路 }rode; bool cmp(const rode &a,const rode &b)//道路按照权值进行从小到大排序 {     if(a.cost < b.cost)         return true;     else         return false; } rode r[5050];//道路数组 int city[101];//村庄数组 int find(int n)//并查集寻找元素集合的代表元素 {     if(city[n] == -1)         return n;     return city[n] = find(city[n]); } bool mergr(int s1,int s2)//集合的合并 {     int r1 = find(s1);     int r2 = find(s2);     if(r1 == r2)         return 0;     else if(r1 < r2)         city[r2] = r1;     else         city[r1] = r2;     return 1; } int main() {     int n,m;     while(cin>>n)     {         if(n==0)             break;         m = (n*(n-1))/2;//道路的数目         memset(city,-1,sizeof(city));//初始化         for(int i = 0;i>r[i].c1>>r[i].c2>>r[i].cost;         }         sort(r,r+m,cmp);//排序         int sum = 0;         int count = 0;         for(int i=0;i < m;++i)         {             if(mergr(r[i].c1,r[i].c2))             {                 count++;                 sum = sum + r[i].cost;             }             if(count == n-1)//选择n-1条道路就跳出             {                 break;             }         }         cout<

你可能感兴趣的:(4最短路径之村庄4)