1. 程式人生 > >C++ P3366 【模板】最小生成樹

C++ P3366 【模板】最小生成樹

不談

直接上程式碼。

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
struct Edge{
	int u,v;
	int w;
};
Edge edgeArray[200000+5];
int pointFatherArray[5000+5];

int compareTo(Edge a,Edge b){
	return a.w<b.w;
}
int find(int x){
	return x==pointFatherArray[x]?x:pointFatherArray[x]=find(pointFatherArray[x]);
}
int kruskal(int pointAmount,int edgeAmount){
	int totalWeight=0;
	int totalEdgeAmount=0;//最小生成樹的邊數 
	for(int i=0;i<edgeAmount;i++){
		Edge edge=edgeArray[i];
		int uPointFather=find(edge.u);
		int vPointFather=find(edge.v);
		if(uPointFather==vPointFather)continue; 
		totalWeight+=edge.w;//注意 不要忘記加總權重啊 
		pointFatherArray[uPointFather]=vPointFather;
		totalEdgeAmount++;
		if(totalEdgeAmount==pointAmount-1){
			return totalWeight;
		}
	}
	return totalWeight;
}
int main(){
	int pointAmount,edgeAmount;
	scanf("%d%d",&pointAmount,&edgeAmount);
	for(int i=0;i<edgeAmount;i++){
		//Edge edge=edgeArray[i];
		//cin>>edge.u>>edge.v>>edge.w; 注意  不要這樣寫!! 
		cin>>edgeArray[i].u>>edgeArray[i].v>>edgeArray[i].w;
	}
	for(int i=1;i<=pointAmount;i++){//不要忘記預處理pointFatherArray
		pointFatherArray[i]=i;
	}
	sort(edgeArray,edgeArray+edgeAmount,compareTo);
	int totalWeight=kruskal(pointAmount,edgeAmount);
	cout<<totalWeight<<endl;
	return 0;
}

怎麼學呢?首先,看紫書,大概看懂之後,你可能是懵逼的。(像我一樣)
接下來我們看一下程式碼。
…程式碼大概挺好懂的QAQ我就不解釋了(其實是不知道咋解釋)

由於這道題的特殊性(只需要求出總權值即可),所以我們直接扔了並查集壓縮路徑(就是讓子結點的父結點直接設定為最大的父結點,這樣訪問子結點的最大的父結點就快了),也就是說我們結束之後沒法輸出最小生成樹的樣子。
某蒟蒻:那麼我該怎麼輸出最小生成樹的樣子呢QAQ
zyc大佬:記錄每一次留下的邊