图论-最小生成树
模板题:寻宝
1.克鲁斯卡尔(并查集)
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef struct{
int w,a,b;
}edge;
edge e[N];
bool cmp(edge a,edge b){
return a.w<b.w;
}
int main()
{
int n,m;
cin>>n>>m;
for(int i=0;i<m;i++){
int w,a,b;
cin>>a>>b>>w;
e[i]={w,a,b};
}
sort(e,e+m,cmp);
int sum=0;
vector<int> fa(n+1);
for(int i=0;i<=n;i++)fa[i]=i;
auto find=[&](auto &&find,int x)->int{
if(fa[x]==x)return x;
return fa[x]=find(find,fa[x]);
};
auto join=[&](int x,int y)->bool{
int xx=find(find,x);
int yy=find(find,y);
if(xx==yy)return 1;
fa[xx]=yy;
return 0;
};
for(int i=0;i<m;i++){
auto [w,a,b]=e[i];
if(join(a,b)==0){
sum+=w;
}
}
cout<<sum<<'\n';
}
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef pair<int,int> PII;
vector<PII>v[N];
int dist[N];
int main()
{
int n,m;
cin>>n>>m;
memset(dist,0x3f,sizeof(dist));
for(int i=0;i<m;i++)
{
int v1,v2,val;
cin>>v1>>v2>>val;
v[v1].push_back({val,v2});
v[v2].push_back({val,v1});
}
vector<int>vis(n+1);
priority_queue<PII,vector<PII>,greater<PII>> q;
q.push({0,1});
int cnt=0;
int sum=0;
while(q.size()&&cnt<n){//n个点都包含了就退出
auto [a,b]=q.top();
q.pop();
if(vis[b])continue;//一个点可能不止一次被放进队列
vis[b]=1;//加入此点
cnt++;
sum+=a;
for(auto [w,u]:v[b]){
if(vis[u])continue;
if(dist[u]<=w)continue;
dist[u]=w;
q.push({w,u});
}
}
cout<<sum<<'\n';
}
浙公网安备 33010602011771号