HDOJ 1233 还是畅通工程
题目传送:HDOJ 1233
解题思路:Kruskal算法,利用Kruskal算法获得最小生成树,即可求得答案。
数据结构:记录下起始坐标,结束坐标,两点距离和该路是否被选中这四个信息。
View Code
struct EDGE{ int x;//起始坐标 int y;//结束坐标 int len;//距离 int fg;//标记是否被选中 }
过程:
1、读取所有路径信息,保存在上述数据结构的数组中;
2、快速排序,使得数组中的数据结构按路径长度从小到大排列;
3、优先选择路径较短的建树,此处为for循环;
4、建树过程中,利用并查集判断该路是否会产生回路,如果回路则抛弃;
5、直到生成一棵树覆盖所有坐标(城市)为止。
题目代码:
#include <stdio.h> #include <stdlib.h> struct EDGE{ int x,y,len,fg; }edge[5000]; int father[110]; int cmp( const void *a ,const void *b) { return (*(EDGE *)a).len > (*(EDGE *)b).len ? 1 : -1; } int find(int a) { while(father[a]!=a) a=father[a]; return a; } int merge(int x,int y) { int fx,fy; fx=find(x); fy=find(y); if(fx==fy) return 0; else { father[fy]=fx; return 1; } } int main() { int n,num,sum,i,p; while(scanf("%d", &n) && n) { num=n*(n-1)/2;//边数 //初始化father[] for(i=1;i<=n;i++) father[i]=i; for(i=0;i<num;i++) { scanf("%d%d%d", &edge[i].x, &edge[i].y, &edge[i].len); edge[i].fg=0; } qsort(edge,num,sizeof(edge[0]),cmp); p=1;//初始化判断位p,1为选择,0为抛弃 sum=0;//初始化sum,记录最短路径长度 for(i=0;i<num;i++) { //利用并查集判断边的两点是否在同一集合内,不在就选择该边,否则抛弃 p=merge(edge[i].x, edge[i].y); if(!p) continue; else { edge[i].fg=1; sum+=edge[i].len; } } printf("%d\n", sum); } return 0; }