比赛 NOIP2025模拟赛3 评测结果 RRRRRRRRRRRRRRRRRRRRRRRRR
题目名称 Phone Plans 最终得分 0
用户昵称 梦那边的美好TE 运行时间 3.544 s
代码语言 C++ 内存使用 3.35 MiB
提交时间 2025-11-26 12:29:56
显示代码纯文本
#include <algorithm> 
#include <iostream>
#include <cstdio>
#include <map>
#define pii pair<int,int>
#define mp make_pair
#define fi first
#define se second
using namespace std;
const int N=2e5+10;
typedef long long ll;
int n,a,b,top,ans;
int fa[N],fb[N],siza[N],sizb[N];
ll ansa,ansb,res,k;
pii stk1[N],stk2[N];
map<pii,int>H;
ll calc(ll v){
	return v*(v-1);
} 
int finda(int x){
	return fa[x]==x?x:finda(fa[x]);
}
int findb(int x){
	return fb[x]==x?x:findb(fb[x]); 
}
int add(int x){
	pii w=mp(finda(x),findb(x));
	res-=calc(H[w]),H[w]++,res+=calc(H[w]);
}
int del(int x){
	pii w=mp(finda(x),findb(x));
	res-=calc(H[w]),H[w]--,res+=calc(H[w]);
}
void mergea(int x,int y){
	int u=finda(x),v=finda(y);
	if(u==v)return;del(x),del(y);
	if(siza[u]>siza[v])swap(u,v);
	ansa+=siza[u]*siza[v];
	fa[u]=v,siza[v]+=siza[u];
	add(x),add(y);return;
}
void mergeb(int x,int y){
	int u=findb(x),v=findb(b);
	if(u==v)return;del(x),del(y);
	if(sizb[u]>sizb[v])swap(u,v);
	cout<<sizb[u]<<" "<<sizb[v]<<" "<<x<<" "<<y<<endl;
	ansb+=sizb[u]*sizb[v];
	fb[u]=v,sizb[v]+=sizb[u];
	stk1[++top]=mp(u,v);
	stk2[top]=mp(x,y);
	add(x),add(y);return;
}
void split(){
	pii w=stk1[top],v=stk2[top--];
	del(v.fi),del(v.se);
	fb[w.fi]=w.fi,sizb[w.se]-=sizb[w.fi];
	ansb-=sizb[w.se]*sizb[w.fi];
	add(v.fi),add(v.se);return;
}
int val(){
	return ansa+ansb-res;
}
struct edge{int u,v,w;}ea[N],eb[N];
bool cmp(edge a,edge b){
	return a.w<b.w;
}
int main(){
	scanf("%d %d %d %lld",&n,&a,&b,&k);
	for(int i=1,u,v,w;i<=a;i++){
		scanf("%d %d %d",&u,&v,&w);
		ea[i]=edge{u,v,w};
	}
	for(int i=1,u,v,w;i<=b;i++){
		scanf("%d %d %d",&u,&v,&w);
		eb[i]=edge{u,v,w};
	}
	sort(ea+1,ea+1+a,cmp);
	sort(eb+1,eb+1+b,cmp);
	for(int i=1;i<=n;i++){
		fa[i]=fb[i]=i;add(i);
		siza[i]=sizb[i]=1;
	}
	//cout<<findb(2)<<endl;
	int i=0,j=b;
	for(int l=1;l<=b;l++)mergeb(eb[l].u,eb[l].v);
	while(i<a&&val()<k)i++,mergea(ea[i].u,ea[i].v);
	if(val()<k){
		printf("-1\n");
	}else{
		ans=ea[i].w+eb[j].w;
//		for(int i=1;i<=n;i++){
//			cout<<i<<"---"<<H[mp(finda(i),findb(i))]<<" "<<res<<endl;
//		}
		
		while(1){
			j--,split();cout<<ansb<<endl;
			while(i<a&&val()<k){
				i++,mergea(ea[i].u,ea[i].v);
				//cout<<i<<" "<<ansa<<" "<<ansb<<" "<<res<<endl;
			}
			if(val()<k)break;
			else ans=min(ans,ea[i].w+eb[j].w);
		}
		printf("%d\n",ans);
	}
	return 0;
}
/*
6 4 4 9

1 2 1
2 3 2
1 4 3
3 4 4

5 6 40
1 5 30
2 6 20
3 6 10
*/