当前位置: 首页 > news >正文

网站不更新即商通网站建设推广

网站不更新,即商通网站建设推广,安徽网络优化公司排名,背景色搭配网站前言 从图开始的每个算法都挺重要的&#xff0c;用途都很广。 一、最小生成树 1.内容 最小生成树是&#xff0c;在无向有权图中选择一些边&#xff0c;保证所有节点都连通且所有边的总权值最小。 2.Kruskal算法——【模板】最小生成树 #include<bits/stdc.h> using…

前言

从图开始的每个算法都挺重要的,用途都很广。

一、最小生成树

1.内容

最小生成树是,在无向有权图中选择一些边,保证所有节点都连通且所有边的总权值最小

2.Kruskal算法——【模板】最小生成树

#include<bits/stdc++.h>
using namespace std;//并查集
vector<int>father; void build(int n)
{father.resize(n+1);for(int i=1;i<=n;i++){father[i]=i;}
}int find(int i)
{if(i!=father[i]){father[i]=find(father[i]);}return father[i];
}bool Union(int x,int y)//Union还要负责判断是否为环 -> 在同一集合 
{int fx=find(x);int fy=find(y);if(fx!=fy){father[fx]=fy;return true;}else{return false;}
}static bool cmp(vector<int>&a,vector<int>&b)
{return a[2]<b[2];
}void solve(int n,int m,vector<vector<int>>&edges)
{build(n);//先按边权从小到大排序sort(edges.begin(),edges.end(),cmp); int ans=0;int edgeCnt=0;for(int i=0;i<m;i++){if(Union(edges[i][0],edges[i][1])){edgeCnt++;ans+=edges[i][2];}}if(edgeCnt==n-1){cout<<ans;	} else{cout<<"orz";}
}void read()
{int n,m;cin>>n>>m;vector<vector<int>>edges(m,vector<int>(3));for(int i=0;i<m;i++){cin>>edges[i][0]>>edges[i][1]>>edges[i][2];}solve(n,m,edges);
}int main()
{ios::sync_with_stdio(false);cin.tie(nullptr);read();return 0;	
} 

Kruskal就是用来最小生成树的算法,其实还有个prim算法,但过程太过复杂了,所以这篇里没写,以后看情况要是真的必须掌握的话再说吧。

Kruskal算法无需建图,但需要借助并查集数据结构与算法:并查集。过程就是先按边权从小到大排序,然后在保证不生成环的情况下,逐渐合并节点,统计总边权。

其中,可以优化Union函数,加入判断是否会生成环,即在同一个集合里。具体方法是让其返回一个bool值,当fx和fy不相等时,在合并后返回true,表示不生成环;否则不合并,返回false,表示会生成环。

二、题目

1.买礼物

#include<bits/stdc++.h>
using namespace std;vector<int>father; void build(int n)
{father.resize(n+1);for(int i=0;i<n;i++){father[i]=i;}
}int find(int i)
{if(i!=father[i]){father[i]=find(father[i]);}return father[i];
}bool Union(int x,int y)
{int fx=find(x);int fy=find(y);if(fx!=fy){father[fx]=fy;return true;}return false;
}static bool cmp(vector<int>&a,vector<int>&b)
{return a[2]<b[2];
}void solve(int a,int n,int cnt,vector<vector<int>>&edges)
{build(cnt);sort(edges.begin(),edges.end(),cmp);int ans=0;for(int i=0;i<cnt;i++){if(Union(edges[i][0],edges[i][1])){ans+=edges[i][2];}}cout<<ans;
}void read()
{int a,n;cin>>a>>n;vector<vector<int>>edges(n*n+n+1,vector<int>(3));int cnt=0;for(int i=1;i<=n;i++,cnt++){edges[cnt][0]=0;edges[cnt][1]=i;edges[cnt][2]=a;}for(int i=0;i<n;i++){for(int j=0,k;j<n;j++,cnt++){edges[cnt][0]=i;edges[cnt][1]=j;cin>>k;edges[cnt][2]=k==0?a:k;}}solve(a,n,cnt,edges);
}int main()
{ios::sync_with_stdio(false);cin.tie(nullptr);read();return 0;
}

这个题唯一的难点就在于单独买一个时的处理,略微思考就能想到,只需要加一个零号节点,让其与所有节点相连,其中每条边就是对应节点自己的权重即可。

处理好数据后就是Kruskal的模板了。

2.检查边长度限制的路径是否存在

class Solution {
public:vector<int>father;vector<bool> distanceLimitedPathsExist(int n, vector<vector<int>>& edgeList, vector<vector<int>>& queries) {int m=edgeList.size();int q=queries.size();        build(n);//记应该填的位置for(int i=0;i<q;i++){queries[i].push_back(i);}//根据limit排序sort(queries.begin(),queries.end(),[&](vector<int>&a,vector<int>&b){return a[2]<b[2];});//根据边权排序sort(edgeList.begin(),edgeList.end(),[&](vector<int>&a,vector<int>&b){return a[2]<b[2];});vector<bool>ans(q);for(int i=0,j=0;i<q;i++){//合并小于limit的边for(;j<m&&edgeList[j][2]<queries[i][2];j++){Union(edgeList[j][0],edgeList[j][1]);}ans[queries[i][3]]=isSameSet(queries[i][0],queries[i][1]);}return ans;}void build(int n){father.resize(n);for(int i=0;i<n;i++){father[i]=i;}}void Union(int x,int y){int fx=find(x);int fy=find(y);if(fx!=fy){father[fx]=fy;}}int find(int i){if(i!=father[i]){father[i]=find(father[i]);}return father[i];}bool isSameSet(int x,int y){return find(x)==find(y);}
};

 这个题就需要一点思考了,由于要求路径上每一条边的权值都小于limit,所以整体思路是,连接所有小于限制的边,生成最小生成树,然后查询要求的两节点是否连通,即在同一集合。

所以考虑先按limit从小到大给查询数组排序,注意为了之后往ans的对应位置输答案,这里要先往每个查询后加入到时候往ans里输的位置。之后遍历每条查询,合并小于limit的边,然后查询是否在同一集合即可。

3.繁忙的都市

#include<bits/stdc++.h>
using namespace std;vector<int>father;void build(int n)
{father.resize(n+1);for(int i=1;i<=n;i++){father[i]=i;}
}int find(int i)
{if(i!=father[i]){father[i]=find(father[i]);}return father[i];
}bool Union(int x,int y)
{int fx=find(x);int fy=find(y);if(fx!=fy){father[fx]=fy;return true;}return false;
}void solve(int n,int m,vector<vector<int>>&edges)
{build(n);sort(edges.begin(),edges.end(),[&](vector<int>&a,vector<int>&b){return a[2]<b[2];});int cnt=0;int Max=0;for(int i=0;i<m;i++){if(Union(edges[i][0],edges[i][1])){cnt++;Max=max(Max,edges[i][2]);//最小生成树必是最小瓶颈树 -> 最大边权最小 }if(cnt==n-1)//最小生成树必是n-1条 {break;}}cout<<n-1<<" "<<Max;
}void read()
{int n,m;cin>>n>>m;vector<vector<int>>edges(m,vector<int>(3));for(int i=0;i<m;i++){cin>>edges[i][0]>>edges[i][1]>>edges[i][2];}solve(n,m,edges);
}int main()
{ios::sync_with_stdio(false);cin.tie(nullptr);read();return 0;	
} 

 这个题有一个结论,就是最小生成树必是最小瓶颈树。最小瓶颈树就是在连通的情况下,要求最大边权最小,即这道题的第三个要求。而有了这个结论之后再思考,可以发现在最小生成树的情况下,这个要求的边数就是n-1。所以只需要统计边的最大值即可。

总结

怎么说呢,最小生成树非常重要。虽然这几个题看上去不是那么吓人,但通常这个还会放在新情境里和其他算法一起出现,那就比较恶心了。

END

http://www.dtcms.com/a/607502.html

相关文章:

  • 如皋做网站wordpress注册会员无法收到邮件
  • c语言编译过程五步骤 | 深入解析编译流程的关键环节
  • 网站开发自学时间财务软件定制开发
  • 在线销售型网站做网站要备案
  • 百度网站地址提交网站建设服务 杭州
  • vue做网站首页wordpress 没有分类目录
  • 哪些网站用.ren域名京东商城网上购物京东超市
  • 市场洞察:从品类到买量,解析韩国手游市场出海新机遇
  • C++ 循环结构:控制程序重复执行的核心机制
  • Jetson ORIN NANO SUPER 装机流程
  • 重庆自助模板建站做自己的网站多少钱
  • 邹城做网站asp网站做视频
  • 青岛网站建设迅优企业信息管理系统查询
  • 做网站对程序员说那些需求自己做链接的网站
  • 上海网站制作工作室东莞外贸建站模板
  • Trae 一键换装 Dracula 主题 + 改注释颜色 + 去掉 console.log 多余分号
  • 工会网站建设策划书it服务商
  • 数据分析笔记04:抽样方法与抽样分布
  • 重庆知名网站电商网站建设外包
  • 创建网站需要什么平台微信小程序怎么做抽签
  • 做瑜珈孕妇高清图网站博客网站的建设流程
  • 个人建网站教程辽宁网站制作公司
  • 学校网站建设开题报告书wordpress整站搬运
  • 秦皇岛公司做网站网站续费怎么做帐
  • 网商之窗官网百度seo
  • 外贸网站中的搜索产品功能如何实现seo网站提交提交
  • 如何在客户临时提出新需求时进行影响评估
  • 源码网站制作教程做视频网站都需要什么
  • 佛山网站运营十年乐云seo网站建设协调会
  • 网站内怎么做链接怎么做游戏推广赚钱