找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 6743|回复: 0

孤岛连通工程

[复制链接]
发表于 2012-2-17 13:52:02 | 显示全部楼层 |阅读模式
作者:Hackbuteer1 发表于2012-2-16 19:31:49 原文链接
题目描述:
现在有孤岛n个,孤岛从1开始标序一直到n,有道路m条(道路是双向的,如果有多条道路连通岛屿i,j则选择最短的那条),请你求出能够让所有孤岛都连通的最小道路总长度。
输入:
数据有多组输入。
每组第一行输入n(1<=n<=1000),m(0<=m<=10000)。
接着m行,每行输入一条道路i j d(0<=d<=1000),(i,j表示岛屿序号,d表示道路长度)。
输出:
对每组输入输出一行,如果能连通,输出能连通所有岛屿的最小道路长度,否则请输出字符串"no"。
样例输入:3 5
1 2 2
1 2 1
2 3 5
1 3 3
3 1 2
4 2
1 2 3
3 4 1样例输出:3
no



  1. #include<iostream>
  2. #include<algorithm>
  3. using namespace std;
  4. #include<stdio.h>
  5. struct Edge
  6. {
  7.         int x;
  8.         int y;
  9.         int cost;
  10. }edge[10001];
  11. int set[10001];
  12. inline int find(int x)           //带路径优化的并查集查找算法
  13. {
  14.     int i,j,r;
  15.     r=x;
  16.     while(set[r]!=r)
  17.         r=set[r];
  18.     i=x;
  19.     while(i!=r)
  20.     {
  21.         j=set[i];
  22.         set[i]=r;
  23.         i=j;
  24.     }
  25.     return r;
  26. }
  27. inline void merge(int x,int y)     //优化的并查集归并算法
  28. {
  29.     int t=find(x);
  30.     int h=find(y);
  31.     if(t<h)
  32.         set[h]=t;
  33.     else
  34.         set[t]=h;
  35. }
  36. /*
  37. int cmp(const void *a,const void *b)
  38. {
  39.         return((*(struct Edge *)a).cost-(*(Edge *)b).cost);
  40. }
  41. */
  42. bool cmp(const Edge& a,const Edge& b)
  43. {
  44.         return a.cost<b.cost;
  45. }
  46. void init(int n)          //初始化并查集,各点为孤立点,分支数为n
  47. {
  48.         for(int i=1;i<=n;i++)
  49.                 set[i]=i;
  50. }
  51. int kruskal(int n,int m)
  52. {
  53.         int i,num,sum,from,to;
  54.         //qsort(edge,m,sizeof(edge[0]),cmp);
  55.         sort(edge,edge+m,cmp);
  56.         sum=num=0;
  57.         for(i=0;i<m;i++)
  58.         {
  59.                 from = find(edge[i].x);    //判断线段的起始点所在的集合  
  60.                 to = find(edge[i].y);      //判断线段的终点所在的集合
  61.                 if(from != to)        //如果线段的两个端点所在的集合不一样  
  62.                 {
  63.                         merge(from,to);    //合并两个集合
  64.                         sum+=edge[i].cost;
  65.                         num++;
  66.                 }
  67.                 if(num==n-1)
  68.                         break;
  69.         }
  70.         if(num<n-1)
  71.                 return -1;
  72.         else
  73.                 return sum;
  74. }
  75. int main(void)
  76. {
  77.         int i,n,m,k;
  78.         while(scanf("%d %d",&n,&m)!=EOF)
  79.         {
  80.                 for(i=0;i<m;i++)
  81.                 {
  82.                         scanf("%d %d %d",&edge[i].x,&edge[i].y,&edge[i].cost);
  83.                 }
  84.                 init(n);
  85.                 k=kruskal(n,m);
  86.                 if(k==-1)
  87.                         printf("no\n");
  88.                 else
  89.                         printf("%d\n",k);
  90.         }
  91.         return 0;
  92. }
复制代码

您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-12-26 22:55 , Processed in 0.014000 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表