最小生成树模板
最小生成树模板
Kruskal:
时间复杂度:\(O(M\log M)\)
#include<bits/stdc++.h>
using namespace std;
int N,M,f[5010],ans;
struct node{
int X,Y,Z;
}e[200010];
bool cmp(node x,node y){
return x.Z<y.Z;
}
void init(){
for(int i=1;i<=N;i++) f[i]=i;
}
int Find(int x){
return f[x]==x?x:f[x]=Find(f[x]);
}
void hebing(int x,int y){
f[Find(x)]=Find(y);
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
cin>>N>>M;init();
for(int i=1;i<=M;i++) cin>>e[i].X>>e[i].Y>>e[i].Z;
sort(e+1,e+1+M,cmp);//读入图信息,排序边
for(int i=1;i<=M;i++){
int u=e[i].X,v=e[i].Y,w=e[i].Z;
if(Find(u)!=Find(v)){//如果u和v不在同一个集合,则合并
ans+=w;//将边权加入最后答案
hebing(u,v);
}
}
for(int i=1;i<=N;i++){
if(Find(i)!=Find(1)){
cout<<"orz";//判断是否最终剩下一个集合,如果不是,输出“orz”
return 0;
}
}
cout<<ans;
return 0;
}
Prim(堆优化):
时间复杂度:\(O((N+M)\log N)\)
#include<bits/stdc++.h>
using namespace std;
using pii=pair<int,int>;
const int MAXN=5005,MAXM=400005;
int N,M,hd[MAXN],ver[MAXM],nxt[MAXM],w[MAXM],tot,dis[MAXN];
bool vis[MAXN];
void add(int u,int v,int c){
ver[++tot]=v;w[tot]=c;nxt[tot]=hd[u];hd[u]=tot;
ver[++tot]=u;w[tot]=c;nxt[tot]=hd[v];hd[v]=tot;
}
int Prim(){
priority_queue<pii,vector<pii>,greater<pii> > q;//小根堆,存(距离,节点编号)
memset(dis,0x7f,sizeof(dis));//初始化距离
dis[1]=0;
q.push({0,1});
int ans=0,cnt=0;//cnt记录加入生成树的节点数
while(q.size()&&cnt<N){
int d=q.top().first,u=q.top().second;q.pop();
if(vis[u]) continue;//为旧值或已访问
vis[u]=true;
ans+=d;cnt++;
for(int i=hd[u];i;i=nxt[i]){//遍历u的所有出边,尝试更新未访问节点的dis
int v=ver[i],c=w[i];
if(!vis[v]&&c<dis[v]){
dis[v]=c;
q.push({c,v});
}
}
}
return (cnt==N)?ans:-1;//如果cnt<n,说明图不连通
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
cin>>N>>M;
for(int i=1,X,Y,Z;i<=M;i++){
cin>>X>>Y>>Z;
add(X,Y,Z);
}
int res=Prim();
if(res==-1) cout<<"orz";
else cout<<res;
return 0;
}

浙公网安备 33010602011771号