您的位置:首页 > 科技 > 能源 > 杭州建模培训_中企动力邮箱登陆网址_推广赚钱app_百度推广没有一点效果

杭州建模培训_中企动力邮箱登陆网址_推广赚钱app_百度推广没有一点效果

2025/2/25 16:41:35 来源:https://blog.csdn.net/qwertf123/article/details/144774435  浏览:    关键词:杭州建模培训_中企动力邮箱登陆网址_推广赚钱app_百度推广没有一点效果
杭州建模培训_中企动力邮箱登陆网址_推广赚钱app_百度推广没有一点效果

目录

题目描述

输入格式:

输出格式:

输入样例:

输出样例:

解题思路:

举个例子:

详细代码:

堆优化的prim详细代码:


题目描述

题目给出一个无向连通图,要求求出其最小生成树的权值。

温馨提示:本题请使用prim最小生成树算法。

输入格式:

第一行包含两个整数 N(1<=N<=1x104),M(1<=M<=2x106) 表示该图共有 N 个结点和 M 条无向边。

接下来 M 行每行包含三个整数 Xi​,Yi​,Zi​ ,表示有一条长度为 Zi​ 的无向边连接结点 Xi​,Yi​ 。

输出格式:

输出一个整数表示最小生成树的各边的长度之和。

输入样例:

4 5
1 2 2
1 3 2
1 4 3
2 3 4
3 4 3

输出样例:

7

解题思路:

思想与dijkstra相同

即从1号点开始,将其纳入集合,查找与其距离最短的边,只需记录该点的终点是否走过,

然后将这条边连接的点也纳入集合中,查找与这个集合距离最短的另一条边,依次进行下去。

举个例子:

根据输入样例

4 5
1 2 2
1 3 2
1 4 3
2 3 4
3 4 3

可以构建一个如图所示的无向图

定义最小生成树总权值sum=0

首先将1号点放入集合中,集合{1}

查找与集合1最近的边为1到2的边权值为2,总权值sum=sum+2=2

之后2进入集合{1,2}

查找与集合最近的边为1到3的边权值为2,总权值sum=sum+2=4

之后3进入集合{1,2,3}

查找与集合最近的边为1到4的边权值为3,总权值sum=sum+3=7

构建最小生成树如下图

此时集合中有{1,2,3,4}全都被标记在集合中

详细代码:

#include <iostream>
#include <cstring>
#include <algorithm> 
#include <vector>
using namespace std;const int N=1e5+7;
struct asd{int x,y;
};
vector<asd>ljb[N];
int dist[N];//当前点i到集合的最短距离
int st[N];//等于1在集合中,等于0不在集合中
int n, m;
int prim(){memset(dist,0x3f,sizeof dist);int res=0;//计算生成树最小权值for (int i=0;i<n;i++) {int t=-1;for (int j=1;j<=n;j++) {if (st[j]==0&&(t==-1||dist[t]>dist[j]))//找到当前离集合最短距离的点t=j;}if(i){res+=dist[t];}st[t]=1;for (int j=0;j<ljb[t].size();j++) {asd ls=ljb[t][j];dist[ls.x]=min(dist[ls.x],ls.y);//更新点到集合的最短距离}}return res;
}
int main() {scanf("%d %d",&n,&m);while(m--){int a,b,c;scanf("%d %d %d",&a,&b,&c);;ljb[a].push_back({b,c});//邻接表储存边信息ljb[b].push_back({a,c});}int t=prim();printf("%d",t);
}

堆优化的prim详细代码:

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;const int N = 1e4+10;typedef pair<int,int> PII;//用PTT替换pair<int,int>文本vector<PII>ljb[N]; 
bool vis[N];//记录是否走过
int dis[N];
int n,m;void prim()
{memset(dis,0x3f,sizeof dis);//将其他点到集合的距离设为无穷大dis[1] = 0;//初始化1到集合的距离int res = 0;priority_queue<PII,vector<PII>,greater<PII>> q;//优先队列,将距离更小的放在前面q.push({0,1});while(!q.empty()){int t = q.top().second;//取出当前出队的点q.pop();if(vis[t]) continue;//如果走过即跳过vis[t] = true;//走了则标记res += dis[t];//记录最小生成树的权值for(auto ls:ljb[t])//遍历与t相邻的点的距离{int k=ls.first,w=ls.second;if(dis[k]>w)//如果之前更新的相邻点的与当前点的距离大于现在更新的距离则替换{dis[k]=w;q.push({w,k});//将距离和该点入队}}}printf("%d",res);
}int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=m;i++){int u,v,w;scanf("%d%d%d",&u,&v,&w);ljb[u].push_back({v,w});//邻接表存储边信息ljb[v].push_back({u,w});}prim();return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com