前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >最小生成树

最小生成树

作者头像
AngelNH
发布2020-04-16 15:22:31
5970
发布2020-04-16 15:22:31
举报
文章被收录于专栏:AngelNI

加油!活成自己喜欢的样子,干嘛要在意别人的眼光。

最小生成树,学了好久了,理论学起来简单易懂,代码一直也没写,今天补起来。

自己太菜了,只能背板子了。

我只是板子的搬运工,哪里需要哪里套。

最小生成树——水题HDU1233

Kruskal

代码语言:javascript
复制
#include<iostream>
#include<algorithm>
using namespace std;
int n;
struct node
{
    int x,y;
    int w;
}mp[10000];
int pre[10000];
bool cmp(node a,node b)
{
    return a.w<b.w;
}
int find(int x)
{
    if(pre[x]==x)
        return x;
    else
    {
        return pre[x] = find(pre[x]);
    }
    
    
}
void join(int x,int y)
{
    int fx = find(x),fy = find(y);
    if(x!=fy)
    {
        pre[fx] = fy;
    }
}
int main()
{
    while(cin>>n)
    {
        for(int i =1;i<=n;++i)//并查集初始化
            pre[i] = i;
        for(int i =1;i<=n;++i)
        {
            cin>>mp[i].x>>mp[i].y>>mp[i].w;
        }
        int N =(n-1)*n/2;//n个顶点可能共有这些边
        sort(mp+1,mp+1+n,cmp);//kruskal算法从最小边开始
        int k = 0,sum=0;
        for(int i =1;i<=N;++i)
        {
            if(k==n-1)//n个顶点的连通图最少有n-1条边
                break;
            if(find(mp[i].x)!=find(mp[i].y))//判断顶点是否被访问,未访问,则归为一家 join
            {
                k++;
                join(mp[i].x,mp[i].x);
                sum+=mp[i].w;//记录最小距离
            }
        }
        cout<<sum<<endl;

    }
    return 0;
}

Prim

代码语言:javascript
复制
#include<iostream>
#include<cstring>
using namespace std;
#define INF 0x3f3f3f3f 
int n;
int mp[10000][10000];
int vis[10000];
int dis[10000];
int ans;
void prim(int n)
{
    for(int i=1;i<=n;++i)
        dis[i] = mp[1][i];
    dis[1] = 0;
    vis[1] = 1;
    for(int i =2;i<=n;++i)
    {
        int t =INF,k;
        for(int j=1;j<=n;++j)
        {
            if(!vis[j]&&dis[j]<t)
            {
                t = dis[j];
                k = j;
            }
        }
        if(t==INF)
            break;
        vis[k] = 1;
        ans+=t;
        for(int j=1;j<=n;++j)
        {
            if(!vis[j]&&dis[j]>mp[k][j])
                dis[j] = mp[k][j];
        }
        
    }
    cout<<ans<<endl;
}
int main()
{
    while(cin>>n&&n)
    {
        ans = 0;
        int m = (n-1)*n/2;
        memset(vis,0,sizeof(vis));
        for(int i =1;i<=m;++i)
        {
            int x,y,w;
            cin>>x>>y>>w;
            mp[x][y] = mp[y][x] = w;
        }
        prim(n);
    }
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-12-07|,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Kruskal
  • Prim
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档