题目转自hdu 1102,题目传送门


题目大意:

输入一个n*n的邻接矩阵,其中i行j列代表从i到j的路径的长度

然后又m条路已经帮你修好了,求最短要修多长的路才能使所有村庄连接

不难看出,这道题就是标准的最小生成树模板,多水啊


解题思路

虽然很水,但本人还是调了近1h才把代码调好......

下面介绍一下解决最小生成树的两个方法:

Prim 和 Kruskal


一,Prim(不懂的点这里)

Prim的思想和dijkstra的想法很想(如果不知道dijkstra算法的请点这里)

那么Prim的复杂度在为优化之前是O(n2),还是很慢的(虽然这道题能过)

既然这样,那这道题该怎么用Prim解呢?

思考了近10min后我想到了一个绝妙的方法,但是这里地方太小写不下

既然已经有建好了的,那我们肯定要用他已经建好的

所以,我们在输入时做一个预处理

将所有已经建过的路的距离化为0,然后再跑一遍Prim就行了

预处理代码如下:

for(int i=;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
g[x][y]=g[y][x]=;
}

p.s.:g为邻接矩阵

然后在花15min打一遍Prim算法就可以愉快地AC了

AC代码如下:

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#define inf 2147483647
using namespace std;
bool vis[];
int n,m,cnt,ans,u;
int dis[];
int g[][];
void init()
{
ans=cnt=;
memset(vis,false,sizeof(vis));
memset(dis,0x7f,sizeof(dis));
return ;
}
void pirm()
{
dis[]=;
while(true)
{
u=;
for(int i=;i<=n;i++)
if(!vis[i] && (dis[i]<dis[u])) u=i;
if(u==) return ;
vis[u]=true;
ans+=dis[u];
for(int i=;i<=n;i++) dis[i]=min(dis[i],g[u][i]);
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
init();
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
scanf("%d",&g[i][j]);
scanf("%d",&m);
for(int i=;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
g[x][y]=g[y][x]=;
}
pirm();
printf("%d\n",ans);
}
return ;
}

接下来看Kruskal......


二,Kruskal(不懂的点这里)

Kruskal中将用到hdu 1198中的并查集(点此转到我的的博客:图论问题(1):hdu 1198

Kruskal主要就是把边按边权从小到大排序

在通过并查集检查目前最小的边的两端是否在同一集合中

若是,则跳过这条边

否则就把他们归为一个集合

这里只需要提前作这一步骤就行了

预处理代码如下:

for(int i=;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
Union(x,y);
}

p.s.:其中Union为合并函数

然后就花个20min写完模板就可以愉快地AC了

AC代码如下:

#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
struct edge
{
int from,to,w;
bool operator<(const edge &a)const
{
return w<a.w;
}
}e[];
int n,m,cnt,ans;
int fa[];
void init()
{
for(int i=;i<=n;i++) fa[i]=i;
cnt=ans=;
return ;
}
int find_fa(int x)
{
if(x==fa[x]) return x;
else
{
fa[x]=find_fa(fa[x]);
return fa[x];
}
return ;
}
void Union(int x,int y)
{
x=find_fa(x);
y=find_fa(y);
if(x<y) fa[y]=x;
else fa[x]=y;
return ;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
init();
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
{
scanf("%d",&e[cnt].w);
e[cnt].from=i;e[cnt].to=j;
cnt++;
}
scanf("%d",&m);
for(int i=;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
Union(x,y);
}
sort(e,e+cnt);
for(int i=;i<cnt;i++)
if(find_fa(e[i].from)!=find_fa(e[i].to))
{
Union(e[i].from,e[i].to);
ans+=e[i].w;
}
printf("%d\n",ans);
}
return ;
}

今天的讲解就到这了,若果有没有听懂的可以借鉴一下《啊哈!算法》

图论问题(2) : hdu 1102的更多相关文章

  1. HDU 1102 最小生成树裸题,kruskal,prim

    1.HDU  1102  Constructing Roads    最小生成树 2.总结: 题意:修路,裸题 (1)kruskal //kruskal #include<iostream> ...

  2. HDU 1102 Constructing Roads, Prim+优先队列

    题目链接:HDU 1102 Constructing Roads Constructing Roads Problem Description There are N villages, which ...

  3. hdu 1102 Constructing Roads Kruscal

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1102 题意:这道题实际上和hdu 1242 Rescue 非常相似,改变了输入方式之后, 本题实际上更 ...

  4. hdu 1102 Constructing Roads(最小生成树 Prim)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1102 Problem Description There are N villages, which ...

  5. HDU 1102(Constructing Roads)(最小生成树之prim算法)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1102 Constructing Roads Time Limit: 2000/1000 MS (Ja ...

  6. hdu 1102 Constructing Roads (Prim算法)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1102 Constructing Roads Time Limit: 2000/1000 MS (Jav ...

  7. hdu 1102 Constructing Roads (最小生成树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1102 Constructing Roads Time Limit: 2000/1000 MS (Jav ...

  8. HDU 1102 Constructing Roads (最小生成树)

    最小生成树模板(嗯……在kuangbin模板里面抄的……) 最小生成树(prim) /** Prim求MST * 耗费矩阵cost[][],标号从0开始,0~n-1 * 返回最小生成树的权值,返回-1 ...

  9. hdu 1102(最小生成树)

    Constructing Roads Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

随机推荐

  1. D3力布图绘制--节点跑掉,单曲线弯曲问题记录

    D3力布图绘制中遇到的交互问题,频繁操作数据后,会出现节点跑掉和单曲线弯曲的问题 问题描述 在id指向都正常的情况下出现以下2种状况: 单曲线弯曲 节点跑掉 经排查,是数据重复导致的问题 线条也是一样 ...

  2. 应用层内存溢出/越界/重复释放等问题检查工具(ASan)

    https://github.com/google/sanitizers/wiki https://github.com/google/sanitizers/wiki/AddressSanitizer ...

  3. 关于VS2017离线安装的一点扩充说明

    转自:https://www.cnblogs.com/dunitian/p/8051985.html 其实逆天不推荐自己慢慢离线,找个离线包更新下再打包更快 Key:http://www.cnblog ...

  4. 【洛谷5437】【XR-2】约定(拉格朗日插值)

    [洛谷5437][XR-2]约定(拉格朗日插值) 题面 洛谷 题解 首先发现每条边除了边权之外都是等价的,所以可以考虑每一条边的出现次数. 显然钦定一条边之后构成生成树的方案数是\(2*n^{n-3} ...

  5. 【UOJ#62】【UR #5】怎样跑得更快(莫比乌斯反演)

    [UOJ#62][UR #5]怎样跑得更快(莫比乌斯反演) 题面 UOJ 题解 众所周知,\(lcm(i,j)=\frac{ij}{gcd(i,j)}\),于是原式就变成了: \[\sum_{j=1} ...

  6. 基于Spark的电影推荐系统(推荐系统~7)

    基于Spark的电影推荐系统(推荐系统~7) 22/100 发布文章 liuge36 第四部分-推荐系统-实时推荐 本模块基于第4节得到的模型,开始为用户做实时推荐,推荐用户最有可能喜爱的5部电影. ...

  7. 从零开始实现放置游戏(六)——实现后台管理系统(4)Excel批量导入

    前面我们已经实现了在后台管理系统中,对配置数据的增删查改.但每次添加只能添加一条数据,实际生产中,大量数据通过手工一条一条添加不太现实.本章我们就实现通过Excel导入配置数据的功能.这里我们还是以地 ...

  8. Linux 的一些命令记录

    FTP:https://www.cnblogs.com/leoxuan/p/8329998.html YUM:https://blog.csdn.net/allyli0022/article/deta ...

  9. Telegram APIs中文介绍

    Telegram APIs 我们为开发者提供了两种API,Bot API (机器人API) 允许你很轻松地用Telegram的接口创建程序,Telegram API 和DLib 允许你创建定制自己的T ...

  10. 5.如何基于 dubbo 进行服务治理、服务降级、失败重试以及超时重试?

    作者:中华石杉 面试题 如何基于 dubbo 进行服务治理.服务降级.失败重试以及超时重试? 面试官心理分析 服务治理,这个问题如果问你,其实就是看看你有没有服务治理的思想,因为这个是做过复杂微服务的 ...