【贪心】畅通工程系列1-HDU1863 畅通工程-kruskal算法

题目

http://acm.hdu.edu.cn/showproblem.php?pid=1863

问题分析

这道题目求使全省畅通的最低成本,把村庄作为顶点,把道路作为边,那么该题即求最小生成树的总边权值。

算法

算法核心

其实我觉得kruskal算法也是一种贪心,就是每次都选择权重最小的边(也就是成本最低的道路),看这条边的两个顶点是否处在同一个连通分支中,如果不在同一个连通分支中,那么就选上这条边,直至整个图连通,也就是形成最小生成树。

数据结构

本题采用并查集,这种结构的两个主要方法就是查找和合并,查找即查找当前结点的根结点,合并就是将两个连通分支合为一个。为了避免出现线性结构而造成不必要的开支,可以进行优化,即在查找时如果x的根结点不是x,就让root[x]=find(root[x]),这个语句可以理解为将x结点直接连到根结点上。合并时,也是将这两个分支的根结点合并。

算法流程

首先将所有结点的根结点初始化为本身,因为一开始并没有路,然后将边按照权重从小到大排序,之后进行遍历,如果当前边的两个顶点的不在同一个连通分支内,即两个顶点的根结点不同,则选择这条边,边数增加,成本增加,将两个顶点所在的连通分支合并,即根据根结点的大小关系决定把谁的根结点连到另一个的根结点上(直接赋值即可),循环直至边数等于顶点数-1(树的性质)。

代码实现

#include
#include
using namespace std;
const int maxn=105;

struct road
{
    int b;//起点
    int e;//终点
    int v;//成本
} a[maxn*maxn/2];

int root[maxn];
int n,m;//道路数,村庄数
int ans;//最低成本
int cnt;//要修建的道路数目

void init()
{
    for(int i=0; i>n>>m&&n)
    {
        int i;
        for(i=1; i<=n; ++i)
            cin>>a[i].b>>a[i].e>>a[i].v;
        kruskal();
        if(cnt==m-1)
            cout<

你可能感兴趣的:(算法,贪心,kruskal,HDU,畅通工程)