題目1347:孤島連通工程

http://ac.jobdu.com/problem.php?pid=1347

用getchar讀取數據居然可以少這麼多,比起scanf整整少了320ms

並查集優化:

(1)路徑壓縮

我們找到最久遠的祖先時“順便”把它的子孫直接連接到它上面

int findSet(int x){
	if(fa[x]==-1)
		return x;
	int ret=findSet(fa[x]);
	fa[x]=ret;
	return ret;
}

(2)

Rank合併

合併時將元素所在深度低的集合合併到元素所在深度高的集合

void unionSet(int x,int y,int dd){
	int root1=findSet(x);
	int root2=findSet(y);
	if(root1!=root2){
		sum+=dd;
		cnt++;
		if(rank[root1]<rank[root2]){
			fa[root1]=root2;
		}
		else{
			fa[root2]=root1;
			if(rank[root1]==rank[root2])
				rank[root1]++;
		}
	}
}

// 題目1343:城際公路網.cpp: 主項目文件。

#include "stdafx.h"
#include <cstdio>
#include <vector>
#include <algorithm>
using std::sort;
using std::vector;

const int N=1003;
int fa[N],rank[N];
typedef struct Edge{
	int u,v,dd;
	Edge(int _u,int _v,int _dd):u(_u),v(_v),dd(_dd){}
}Edge;
vector<Edge> edge;
int n,sum,cnt;

bool cmp(Edge m1,Edge m2){
	return m1.dd<m2.dd;
}

inline void read(int &d){
	char ch=getchar();
	while(ch<'0'||ch>'9')
		ch=getchar();
	d=0;
	do{
		d=d*10+ch-'0';
		ch=getchar();
	}while(ch>='0'&&ch<='9');
}

void init(){
	for(int i=1;i<=n;i++){
		fa[i]=-1;
		rank[i]=1;
	}
}

int findSet(int x){
	if(fa[x]==-1)
		return x;
	int ret=findSet(fa[x]);
	fa[x]=ret;
	return ret;
}

void unionSet(int x,int y,int dd){
	int root1=findSet(x);
	int root2=findSet(y);
	if(root1!=root2){
		sum+=dd;
		cnt++;
		if(rank[root1]<rank[root2]){
			fa[root1]=root2;
		}
		else{
			fa[root2]=root1;
			if(rank[root1]==rank[root2])
				rank[root1]++;
		}
	}
}

void kruskal(){
	sum=0,cnt=0;
	for(vector<Edge>::iterator ite=edge.begin();ite!=edge.end();++ite)
		unionSet(ite->u,ite->v,ite->dd);
	if(cnt==n-1)
		printf("%d\n",sum);
	else
		printf("no\n");
}

int main()
{
	int m;
	while(~scanf("%d%d",&n,&m)){
		edge.clear();
		for(int i=0;i<m;i++){
			int u,v,dd;
			read(u),read(v),read(dd);
			Edge e(u,v,dd);
			edge.push_back(e);
		}
		sort(edge.begin(),edge.end(),cmp);
		init();
		kruskal();
	}
	return 0;
}

參考:

九度kingwolfofsky代碼

維基百科並查集路徑優化

發佈了145 篇原創文章 · 獲贊 3 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章