HDOJ6958KD-Graph(并查集)

Posted 小哈里

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDOJ6958KD-Graph(并查集)相关的知识,希望对你有一定的参考价值。

1009 KD-Graph

题意:

  • 给出一张n个点m条边的加权无向图和一个整数K,求一个数字D可以将图分为K组,组内任意两点存在路径且小于等于D,组外不存在小于等于D的路径。不存在D输出-1。

思路:

  • 将边按权值从小到大排序,每一阶段取出同权值的所有边,将这些边的端点用并查集两两合并,若某一阶段的全部边合并完,并查集数量为k,则当前阶段合并边的权值就是答案,否则输出-1。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 3e6+10;

struct Edge{int u,v,w;}e[maxn];
bool cmp(Edge a, Edge b){return a.w<b.w;}

int fa[maxn+10];
void init(int n){for(int i = 0; i <= n; i++)fa[i]=i;}
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
void merge(int x, int y){x=find(x);y=find(y);if(x!=y)fa[x]=y;}
int count(int n){int cnt=0; for(int i = 1; i <= n; i++)if(fa[i]==i)cnt++;return cnt;}

int main(){
	ios::sync_with_stdio(false);
	int T;  cin>>T;
	while(T--){
		int n, m, k;  cin>>n>>m>>k;
		for(int i = 1; i <= m; i++)
			cin>>e[i].u>>e[i].v>>e[i].w;
		init(n);
		sort(e+1,e+m+1,cmp);
		int now = n, ans = 0, ok = 0; //now表示刚开始有n组(当前并查集个数)
		for(int i = 1; i <= m; i++){
			if(e[i].w != e[i-1].w){
				if(now==k){//直到分成k组,此时的最大ans满足组外不存在小于等于它的路径
					cout<<ans<<"\\n";
					ok = 1;
					break;
				}
			}
			//如果两点间已经有更小的路径就不管
			if(find(e[i].u)==find(e[i].v))continue;
			//用这条边去合并,将合并的点放入同一组
			merge(e[i].u, e[i].v);
			now--;//组数-1(并查集个数-1)
			ans = e[i].w; //组内<=D(不断变大)
		}
		if(ok==0)cout<<(now==k?ans:-1)<<"\\n";
	}
	return 0;
}

以上是关于HDOJ6958KD-Graph(并查集)的主要内容,如果未能解决你的问题,请参考以下文章

2021杭州多校第一场KD-Graph(思维+并查集)

2021“MINIEYE杯”中国大学生算法设计超级联赛 6958. KD-Graph

并查集——HDOJ-1232-畅通工程

HDOJ 5652 India and China Origins(并查集)

HDOJ图论题集

HDOJ-1232 畅通工程并查集裸题