/* 问题:有任意两个村庄的距离,使全省任意两个村庄之间都可以畅通(不要求直接相连,间接联通也可以),要求铺设公路最短和次最短。请计算最小公路总长度 输入:第一行给出村庄数N(<100),随后的N(N-1)/2给出村庄之间的距离,每行给出一对正整数,分别是两个村庄的编号,以及两个村庄之间的距离。村庄从1到N编号,N=0时结束 输出:求出最短公路总长度 输入: 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 输出: 3 5 思路:利用并查集,这里要设置一条边来进行比较 关键:快速排序edge[low] <=iPos <= edge[high],而不是edge[low] < iPos,需要重载<=,而不是< */ #include <stdio.h> #include <string.h> #include <stdlib.h> #define N 1000 int Tree[N]; //设定边结构体 typedef struct Edge { int _iV1,_iV2;//设定边的起始节点 int _iWeight;//设定权重 //快速排序必须重载<=而不是< bool operator <= (const Edge& edge) { return _iWeight <= edge._iWeight; } }Edge; //并查集寻找根结点的路径压缩函数 int findRoot(int x) { if(-1==Tree[x]) { return x; } else { //寻找当前节点父节点的根结点 int iRoot = findRoot(Tree[x]); //设定当前节点的父节点为根结点 Tree[x] = iRoot; //返回父节点 return iRoot; } } //这个快速排序有问题,小于等于需要动 int partition(Edge* edge,int low,int high) { Edge iPos = edge[low]; while(low < high) { while(low < high && iPos <= edge[high]) { high--; } edge[low] = edge[high];//比枢轴小的元素移动到左端 while(low < high && edge[low] <= iPos) { low++; } edge[high] = edge[low];//比枢轴大的元素移动到右端 } edge[low] = iPos; return low; } void quickSort(Edge* edge,int low,int high) { if(low < high) { int iPos = partition(edge,low,high); quickSort(edge,low,iPos-1); quickSort(edge,iPos+1,high); } } int main(int argc,char* argv[]) { int iNum,i; while(EOF!=scanf("%d",&iNum) && iNum!=0) { //int iV1,iV2,iWeight; //获取输入信息 Edge edgeArr[100]; //初始化并查集 for(i = 0 ; i < N ; i++) { Tree[i] = -1; } //for(i = 0 ; i < iNum ; i++),这里的边总共有iNum*(iNum-1),初始时进行根结点归并,最多只需要iNum*(iNum-1)/2-1条边 for(i = 0 ; i < iNum*(iNum-1)/2; i++) { scanf("%d %d %d",&edgeArr[i]._iV1,&edgeArr[i]._iV2,&edgeArr[i]._iWeight); /* iV1 = findRoot(iV1); iV2 = findRoot(iV2); if(iV1!=iV2) { Tree[iV1] = iV2; } */ } //进行按权值进行快速排序边,易错,边的个数是iNum*(iNum-1)/2 quickSort(edgeArr,0,iNum*(iNum-1)/2-1); int iWeightSum = 0 ; for(i = 0 ; i < iNum*(iNum-1)/2 ; i++) { int iRoot1 = findRoot(edgeArr[i]._iV1); int iRoot2 = findRoot(edgeArr[i]._iV2); if(iRoot1!=iRoot2) { Tree[iRoot1] = iRoot2; iWeightSum += edgeArr[i]._iWeight; } } printf("%d\n",iWeightSum); } system("pause"); getchar(); return 0; } /* 问题:有任意两个村庄的距离,使全省任意两个村庄之间都可以畅通(不要求直接相连,间接联通也可以),要求铺设公路最短和次最短。请计算最小公路总长度 输入:第一行给出村庄数N(<100),随后的N(N-1)/2给出村庄之间的距离,每行给出一对正整数,分别是两个村庄的编号,以及两个村庄之间的距离。村庄从1到N编号,N=0时结束 输出:求出最短公路总长度 输入: 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 输出: 3 5 思路:利用并查集,这里要设置一条边来进行比较 关键:快速排序edge[low] <=iPos <= edge[high],而不是edge[low] < iPos,需要重载<=,而不是< */ #include <stdio.h> #include <string.h> #include <stdlib.h> #define N 1000 int Tree[N]; //设定边结构体 typedef struct Edge { int _iV1,_iV2;//设定边的起始节点 int _iWeight;//设定权重 //快速排序必须重载<=而不是< bool operator <= (const Edge& edge) { return _iWeight <= edge._iWeight; } }Edge; //并查集寻找根结点的路径压缩函数 int findRoot(int x) { if(-1==Tree[x]) { return x; } else { //寻找当前节点父节点的根结点 int iRoot = findRoot(Tree[x]); //设定当前节点的父节点为根结点 Tree[x] = iRoot; //返回父节点 return iRoot; } } //这个快速排序有问题,小于等于需要动 int partition(Edge* edge,int low,int high) { Edge iPos = edge[low]; while(low < high) { while(low < high && iPos <= edge[high]) { high--; } edge[low] = edge[high];//比枢轴小的元素移动到左端 while(low < high && edge[low] <= iPos) { low++; } edge[high] = edge[low];//比枢轴大的元素移动到右端 } edge[low] = iPos; return low; } void quickSort(Edge* edge,int low,int high) { if(low < high) { int iPos = partition(edge,low,high); quickSort(edge,low,iPos-1); quickSort(edge,iPos+1,high); } } int main(int argc,char* argv[]) { int iNum,i; while(EOF!=scanf("%d",&iNum) && iNum!=0) { //int iV1,iV2,iWeight; //获取输入信息 Edge edgeArr[100]; //初始化并查集 for(i = 0 ; i < N ; i++) { Tree[i] = -1; } //for(i = 0 ; i < iNum ; i++),这里的边总共有iNum*(iNum-1),初始时进行根结点归并,最多只需要iNum*(iNum-1)/2-1条边 for(i = 0 ; i < iNum*(iNum-1)/2; i++) { scanf("%d %d %d",&edgeArr[i]._iV1,&edgeArr[i]._iV2,&edgeArr[i]._iWeight); /* iV1 = findRoot(iV1); iV2 = findRoot(iV2); if(iV1!=iV2) { Tree[iV1] = iV2; } */ } //进行按权值进行快速排序边,易错,边的个数是iNum*(iNum-1)/2 quickSort(edgeArr,0,iNum*(iNum-1)/2-1); int iWeightSum = 0 ; for(i = 0 ; i < iNum*(iNum-1)/2 ; i++) { int iRoot1 = findRoot(edgeArr[i]._iV1); int iRoot2 = findRoot(edgeArr[i]._iV2); if(iRoot1!=iRoot2) { Tree[iRoot1] = iRoot2; iWeightSum += edgeArr[i]._iWeight; } } printf("%d\n",iWeightSum); } system("pause"); getchar(); return 0; }