| 比赛 |
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
*/