0
点赞
收藏
分享

微信扫一扫

洛谷 P3366 【模板】最小生成树

龙毓七七 2022-02-17 阅读 72

用的kruskal算法,用到了并查集,算法思路和代码实现过程都很好理解,标准的模板题

#include<bits/stdc++.h>
using namespace std;

const int N=5005;
const int M=200005;

int n,m;//n个节点,m条无向边
long long int lens=0;//最小生成树的各边的长度之和
int cnt=0;//连接上的边数 
int parent[N];//父节点 

struct Edge
{
	int x,y,z;//两顶点和一边 
}edge[M];

void initial()//初始化 
{
	for(int i=0;i<n;i++)
	{
		parent[i]=-1;
	}
}

int find_root(int x)//寻找根结点 
{
	int x_root=x;
	while(parent[x_root]!=-1)
	{
		x_root=parent[x_root];
	}
	return x_root;
}

inline bool cmp(Edge a,Edge b)
{
    return a.z<b.z;
}

inline void kruskal()
{
	sort(edge,edge+m,cmp);//将边按权值排序 
	for(register int i=0;i<m;i++)//重新接上m条边 
    {
    	//用到了并查集 
        int x_root=find_root(edge[i].x);
		int y_root=find_root(edge[i].y);
        if(x_root==y_root)
        {
            continue;//两个点已经连通,不再需要这条边 
        }
        
        lens+=edge[i].z;//未连通则将此边权值加入总长 
        parent[y_root]=x_root,cnt++;//连接两节点,边数+1 
        
        if(cnt==n-1)
        {
            break;//接上的边数为n-1时,最小生成树创立完毕,循环结束
        }
    }
}

int main()
{
	cin>>n>>m;
	for(int i=0;i<m;i++)
	{
		cin>>edge[i].x>>edge[i].y>>edge[i].z;
	}//输入 
	
	initial();
	kruskal();
	
	//输出
	if(cnt==n-1) cout<<lens;
	else cout<<"orz";
	
	return 0;
}
举报

相关推荐

0 条评论