题解:P12222 [蓝桥杯 2023 国 Java B] 电动车

思路:

这道题一眼是用 Kruskal 求出最小生成树中权值最大的那一条边。

证明:

\(W\) 就是我们所求出最小生成树中权值最大的那一条边的权值。

  1. 因为最小生成树中任意两个顶点之间的路径是唯一的,所以从一个顶点到另一个顶点的所有可能路径中,必然会经过这条权重最大的边。
  2. 假设我们选择一个小于 \(W\) 的电量 \(x\),且起点在权值最大的哪一条边上的一个顶点,到达终点要经过这一条边,那么在就会因为最开始的一条边 \(W\)\(x\) 大而到不了第二个点。

Kruskal 可以完美解决这个问题,因为最后那一条加入的边一定是最小生成树中最长的那一条边。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int ans;
int n,m,k,cnt,p,leb;
int fa[N],b[N],_x[N],_y[N];
struct G{
	int u,ne,w;
}pic[2*N];
int find(int );
bool cmp(G ,G );
bool fx(int ,int );
void add(int ,int ,int );
int main(){
	int u,v,w;
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		cin>>u>>v>>w;
		add(u,v,w);
	}
	for(int i=1;i<=n;i++){
		fa[i]=i;
	}
	sort(pic+1,pic+1+cnt,cmp);
	int tot=0;
	for(int i=1;i<=cnt;i++){
		if(tot==n-1) break;
		int x=pic[i].u;
		int y=pic[i].ne;
		if(fx(x,y)){
			tot++;
			ans=pic[i].w;
		}
	}
	if(tot==n-1) printf("%d",ans);
	else printf("-1");
}
bool cmp(G x,G y){
	return x.w<y.w;
}
void add(int u,int v,int w){
	pic[++cnt].u=u;
	pic[cnt].ne=v;
	pic[cnt].w=w;
}
int find(int x){
	if(fa[x]==x) return x;
	else return fa[x]=find(fa[x]);
}
bool fx(int x,int y){
	int nx=find(x);
	int ny=find(y);
	if(nx==ny) return false;
	else{
		fa[nx]=fa[ny];
		return true;
	}
}
posted @ 2025-04-19 10:52  Eden_star  阅读(5)  评论(0)    收藏  举报
//雪花飘落效果