CSP201703-4地铁修建(并查集实现最小生成树)

题目

试题编号201703-4
试题名称地铁修建
时间限制1s
内存限制256MB
问题描述在这里插入图片描述
输入输出在这里插入图片描述
用例规模在这里插入图片描述

题目分析

我开始是想用dfs去做的,为什么这么想?~~脑子瓦特了!~~没算内存限制,超内存了只给了25分;
后来仔细想一下,这道题是要从1到n的所有路径中找到一条路径,这条路径的最大分段在这几条路径中是最小的。想到这里我们就知道了,还有题目给的一定有通路的条件,这就是从最小生成树找就可以了啊,实现的方法是并查集!
不用找到一整颗树,每次加入边的时候,判断1和n是否联通就好了,一旦加入某条边联通了那么马上输出这条边的权就可以了。

AC代码

#include <iostream>
#include <stdio.h>
#include <queue>
#include <cstring>
#define mem(a) memset(a,0,sizeof(a))
#define rep(i,a,n) for(int i=a;i<n;i++)
#define min(a,b) ((a)>(b)?(b):(a))
using namespace std;
struct node{
	int x;
	int y;
	int z;
	bool operator<(const node &b)const{
		return z>b.z;
	}
	node(int a,int b,int c){
		x=a;
		y=b;
		z=c;
	}
};
int father[100001];
int rankk[100001];
void init(int n){
	rep(i,0,n){
		father[i]=i;
		rankk[i]=0;
	}
}
int find(int x){
	if(x==father[x])return x;
	return father[x]=find(father[x]);
}
bool same(int x,int y){
	return find(x)==find(y);
}
void merge(int a,int b){
	int x=find(a);
	int y=find(b);
	if(x==y)return;
	else{
		if(rankk[x]>rankk[y]){
			father[y]=x;
		}
		else{
			father[x]=y;
			if(rankk[x]==rankk[y])
				rankk[y]++;
		}
	}
}
int main(){
	int n,m;
	int a,b,c;
	scanf("%d%d",&n,&m);
	init(n+1);
	priority_queue<node>q; 
	while(m--){
		scanf("%d%d%d",&a,&b,&c);
		q.push(node(a,b,c));
	}
	int ans;
	while(!q.empty()){
		node k=q.top();
		q.pop();
		if(!same(k.x,k.y)){
			merge(k.x,k.y);
			if(same(1,n)){
				ans=k.z;
				break;
			}
		}
	}
	printf("%d\n",ans);
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值