站外题求调
  • 板块灌水区
  • 楼主wuyugu
  • 当前回复2
  • 已保存回复2
  • 发布时间2025/1/17 14:39
  • 上次更新2025/1/17 17:00:43
查看原帖
站外题求调
1125456
wuyugu楼主2025/1/17 14:39

【一本通提高篇最小生成树】Tree

#include<bits/stdc++.h>
#define int long long
using namespace std;
struct Edge{
	int s,e,w,col;
	bool operator<(Edge x) const{
		if(x.w==w)return col<x.col;
		return w<x.w;
 	}
} a[100086];
int fa[100086],v,e,need,s,t,c,col;
inline int find(int x){
	if(fa[x]==x)return x;
	return fa[x] = find(fa[x]);
}
pair<int,int> check(int x){
	int ans=0,ned=0;
	for(int i=0;i<v;i++)fa[i]=i;
	for(int i=0;i<e;i++){
		if(a[i].col == 0)a[i].w += x;
	} 
	sort(a,a+e);
	for(int i=0;i<e;i++){
		int fs=find(a[i].s),fu=find(a[i].e);
		if(fs!=fu){
			fa[fs] = fu;
			ans += a[i].w;
			if(a[i].col == 0) ned++;
		}
	}
	for(int i=0;i<e;i++){
		if(a[i].col == 0)a[i].w -= x;
	}
	return make_pair(ans,ned);
}
signed main(){
	scanf("%lld%lld%lld",&v,&e,&need);
	for(int i=0;i<e;i++){
		scanf("%lld%lld%lld%lld",&s,&t,&c,&col);
		a[i] = {s,t,c,col};
	}
	int l=-1000,r=1000;
	while(l<r){
		int mid=l+r>>1;
		int t = check(mid).second;
		if(t<need)l = mid+1;
		else r = mid;
	}
	printf("%lld",check(l).first);
	return 0;
}
2025/1/17 14:39
加载中...