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

Huge input, scanf is recommended.

解题思路:①Prim算法的核心就是加点法,每次把离目标集合最小权值的一点加入其中。其算法跟Dijkstra大同小异,不同的是mincost数组记录的是当前点到目标集合的最小权值,下次就取最小权值的端点加入就可以了。其算法时间复杂度是O(n2),适合于稠密图。
②Kruskal算法的核心就是加边法,并且运用到并查集。先将各边权值按升序排列,然后贪心加边,加边时查看当前边的两端点是否为同一个连通图中的两点,如果是的话,就不能纳入目标集合,因为会出现回路,即产生圈,这样就不满足树的定义了,否则将其加入。其原来的时间复杂度是O(n2),使用并查集之后时间复杂度是O(elogn),适合于稀疏图。
AC代码之Prim算法:
 #include<bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = ;
int n,a,b,c,mincost[maxn],cost[maxn][maxn];
bool vis[maxn];
int Prim(){//加点法
for(int i=;i<=n;++i)//这里选取节点1作为起点,mincost为各节点到最小生成树节点集合的最小权值
mincost[i]=cost[][i];
mincost[]=;vis[]=true;//标记已访问
int res=;//计算最小生成树的权值
for(int i=;i<n;++i){
int k=-;//标记为-1
for(int j=;j<=n;++j)//找出到最小生成树节点集合的权值最小的还没入集合的一点
if(!vis[j] && (k==- || mincost[k]>mincost[j]))k=j;
if(k==-)break;//如果还是-1,表示已经完成最小生成树的建立
vis[k]=true;//将节点k纳入最小生成树节点的集合
res+=mincost[k];//加上其权值
for(int j=;j<=n;++j)//更新k的邻接点到最小生成树节点集合的最小权值
if(!vis[j])mincost[j]=min(mincost[j],cost[k][j]);//还没归纳的节点
}
return res;
}
int main()
{
while(~scanf("%d",&n) && n){
memset(vis,false,sizeof(vis));
for(int i=;i<=n;++i){
for(int j=;j<=n;++j)
cost[i][j]=(i==j?:INF);
}
for(int i=;i<=n*(n-)/;++i){
cin>>a>>b>>c;
cost[a][b]=cost[b][a]=c;
}
printf("%d\n",Prim());
}
return ;
}

AC代码之Kruskal算法:

 #include<bits/stdc++.h>
using namespace std;
int n,father[],height[];
struct edge{int u,v,cost;}es[];
bool cmp(const edge& e1,const edge& e2){
return e1.cost<e2.cost;
}
void init_union_find(){//将每个节点当作根节点
for(int i=;i<=n;++i)father[i]=i;
}
int find_father(int x){//递归查找根节点
if(father[x]==x)return x;
else return father[x]=find_father(father[x]);
}
bool same_father(int x,int y){//查找两点的根节点是否相同
return find_father(x)==find_father(y);
}
void unite(int x,int y){
x=find_father(x);
y=find_father(y);
if(x==y)return;//如果为同一个连通图,直接返回
if(height[x]<height[y])father[x]=y;//高度大的当作高度小的父亲
else{
father[y]=x;
if(height[x]==height[y])height[x]++;//如果合并前两棵树的高度相等,加入一节点后树的高度就加1
}
}
int Kruskal(){
sort(es+,es+n*(n-)/+,cmp);//权值按从小到大排序
init_union_find();//并查集的初始化
int res=;
for(int i=;i<=n*(n-)/;++i){
edge e=es[i];
if(!same_father(e.u,e.v)){//如果两点的根节点不同,即为非连通图
unite(e.u,e.v);//归并到同一个集合
res+=e.cost;//加入权值
}
}
return res;
}
int main()
{
while(~scanf("%d",&n) && n){
for(int i=;i<=n*(n-)/;++i)
scanf("%d %d %d",&es[i].u,&es[i].v,&es[i].cost);
memset(height,,sizeof(height));//初始化树的高度为0
printf("%d\n",Kruskal());
}
return ;
}

克鲁斯卡尔简化版代码:

 #include<bits/stdc++.h>
using namespace std;
int n,father[],sum;
struct edge{int u,v,cost;}es[];
bool cmp(const edge& e1,const edge& e2){
return e1.cost<e2.cost;
}
void init_union_find(){//将每个节点当作根节点
for(int i=;i<=n;++i)father[i]=i;
}
int find_father(int x){//递归查找根节点
if(father[x]==x)return x;
else return father[x]=find_father(father[x]);
}
void unite(int x,int y,int z){
x=find_father(x);
y=find_father(y);
if(x!=y){//如果边的两端点的根节点不相同,即分别为非连通图,则可以归并
sum+=z;//加上最小权值
father[x]=y;//将x的父节点改成y,也就是现在x的根节点是y的根节点,注意这里只是简单的修改,和上面归纳到同一个集合不太一样
}
}
int main()
{
while(~scanf("%d",&n) && n){
for(int i=;i<=n*(n-)/;++i)
scanf("%d %d %d",&es[i].u,&es[i].v,&es[i].cost);
sort(es+,es+n*(n-)/+,cmp);//权值按从小到大排序
sum=;init_union_find();//初始化
for(int i=;i<=n*(n-)/;++i)
unite(es[i].u,es[i].v,es[i].cost);
printf("%d\n",sum);
}
return ;
}

题解报告:hdu 1233 还是畅通工程的更多相关文章

  1. HDU.1233 还是畅通工程(Prim)

    HDU.1233 还是畅通工程(Prim) 题意分析 首先给出n,代表村庄的个数 然后出n*(n-1)/2个信息,每个信息包括村庄的起点,终点,距离, 要求求出最小生成树的权值之和. 注意村庄的编号从 ...

  2. HDU 1233 还是畅通工程(Kruskal算法)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1233 还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)   ...

  3. hdu 1233 还是畅通工程 (最小生成树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1233 还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)    ...

  4. hdu 1233 - 还是畅通工程(MST)

    还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  5. HDU 1233 还是畅通工程 (最小生成树 )

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

  6. HDU 1233 还是畅通工程(最小生成树)

    传送门 还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  7. HDU 1233 还是畅通工程 (最小生成树)

    还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  8. hdu 1233 还是畅通工程 并查集or最小生成树

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

  9. hdu 1233:还是畅通工程(数据结构,图,最小生成树,普里姆(Prim)算法)

    还是畅通工程 Time Limit : 4000/2000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submis ...

随机推荐

  1. STM32单片机串口一键下载电路与操作方法详解

    STM32三种启动模式对应的存储介质均是芯片内置的,它们是:1)用户闪存 = 芯片内置的Flash.2)SRAM = 芯片内置的RAM区,就是内存啦.3)系统存储器 = 芯片内部一块特定的区域,芯片出 ...

  2. Codeforces Educational Codeforces Round 17 Problem.A kth-divisor (暴力+stl)

    You are given two integers n and k. Find k-th smallest divisor of n, or report that it doesn't exist ...

  3. WeChat-小程序-tabbar

    WeChat-小程序-tabbar https://developers.weixin.qq.com/miniprogram/dev/framework/config.html#%E5%85%A8%E ...

  4. String类的判断功能

    /* * Object:是类层级结构中的根类,所有的类都直接或间接的继承自该类. * 如果一个方法的形式参数是Object,那么这里我们就可以传递它的任意的子类对象. * * String类的判断功能 ...

  5. HDU 1042 大数计算

    这道题一开始就采用将一万个解的表打好的话,虽然时间效率比较高,但是内存占用太大,就MLE 这里写好大数后,每次输入一个n,然后再老老实实一个个求阶层就好 java代码: /** * @(#)Main. ...

  6. linux命令与技巧

    1.模糊查询:find / -name '*Eclipse*'2.获得管理员权限:sudo -i

  7. Ubuntu 16.04安装Chrome浏览器

    一.先有一个hosts能访问Google 参考:http://www.cnblogs.com/EasonJim/p/5999060.html 二.安装方法有两种,如下所示: 1.下载deb包(推荐) ...

  8. 非常适合新手的jq/zepto源码分析01

    (function(global, factory) { // 查看这里是不是定义成模块,如果定义模块就返回 一个模块 if (typeof define === 'function' &&a ...

  9. wsgi初探

    大半夜的不睡觉,起来看技术文档,我这是什么精神啊~ ok 本文的大部分内容都是阅读 http://wsgi.readthedocs.org/en/latest/ 得来的.下面开始研究 wsgi wsg ...

  10. [JavaEE] Injecting Bean

    So what is a Bean, in JavaEE, any class expect Entity are Bean. One usefully thing in Bean is Depend ...