最小生成树

Kruskal

需要并查集建边中的高级版本

变量

  • Graph<N,N<<1> Kru\texttt{Graph<N,N<<1> Kru}:存生成树。
  • pair<int,pair<int,int> >a[M]\texttt{pair<int,pair<int,int> >a[M]}:暂存边的数组。
  • int m\texttt{int m}:边的个数。

函数

  • bool ask(int n)\texttt{bool ask(int n)}:求点编号为 1n1\sim n 的无向图的最小生成树,若能生成,则返回真,否则返回假。

代码

struct Kruskal{
	Graph<N,N<<1> Kru;
	pair<int,pair<int,int> >a[M];
	int m;
	bool ask(int n){
		m=Kru.tot=0;
		int cnt=0;
        mfs.init(n);
		for(int i=1;i<=n;i++){
			for(int j=G.head[i];j;j=G.nxt[j]){
				int y=G.ver[j];
				int z=G.edge[j];
				if(i<y)
					a[++m]=(make_pair(z,make_pair(i,y)));
			}
		}
		sort(a+1,a+m+1);
		for(int i=1;i<=m;i++){
			int u=a[i].second.first;
			int v=a[i].second.second;
			int w=a[i].first;
			if(mfs.get(u)!=mfs.get(v)){
				mfs.merge(u,v);
				cnt++;
				Kru.add(u,v,w);
				Kru.add(v,u,w);
			}
			if(cnt==n-1)
				return 1;
		}
		return 0;
	}
}tu;

Prim

宏定义

  • #define PT int\texttt{\#define PT int}:图的边权类型。

变量

  • PT a[N][N]\texttt{PT a[N][N]}:表示无向图的邻接矩阵。
  • PT d[N]\texttt{PT d[N]}:到节点 11 的距离。
  • bool v[N]\texttt{bool v[N]}:标记一个点是否已在生成树内。

函数

  • PT ask(int n)\texttt{PT ask(int n)}:求点编号为 1n1\sim n 的无向图的最小生成树,返回生成树的边权之和。

代码

#define PT int
PT a[N][N];
struct Prim{
	PT d[N];
	bool v[N];
	PT ask(int n){
		memset(d,0x3f,sizeof(d));
		memset(v,0,sizeof(v));
		d[1]=0;
		PT ans=0;
		for(int i=1,x;i<n;i++){
			x=0;
			for(int j=1;j<=n;j++)
				if(!v[j]&&(!x||d[j]<d[x]))
					x=j;
			v[x]=1;
			for(int j=1;j<=n;j++)
				if(!v[j])
					d[j]=min(d[j],a[x][j]);
		}
		for(int i=2;i<=n;i++)
			ans+=d[i];
		return ans;
	}
}tu;
posted @ 2022-09-12 11:31  luckydrawbox  阅读(8)  评论(0)    收藏  举报  来源