题意:
给定n个城市,m条边,要求必须增加p条路径,实现最后只有q个连通块。
注意:
在给出数据时加和直接加,在自己添加路径时,连通块更新的和= 连通块a + 连通快b +1 (之后的)+ 连通快a +连通块b(之前的)。
真是B了狗了,这个加和没看明白WA36,怼了4个多小时
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <queue>
using namespace std;
struct node
{
long long ft,sum;
friend bool operator <(node a,node b)
{
return a.sum>b.sum;
}
};
const int maxn=1e5+5;
priority_queue <node> s;
int father[maxn];
long long sum[maxn];
int find(int x)
{
if(father[x]!=x)
{
father[x]=find(father[x]);
}
return father[x];
}
const long long inf=1e+9;
int main()
{
int n,m,p,q;
cin>>n>>m>>p>>q;
for(int i=1;i<=n;i++)
{
father[i]=i;
sum[i]=0;
}
int cnt=0;
int x,y,z;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
int rx=find(x);
int ry=find(y);
if(rx!=ry)
{
father[rx]=ry;
sum[ry]+=sum[rx]+z;
if(sum[ry]>=inf)
sum[ry]=inf;
}
else
{
sum[ry]+=z;
}
}
for(int i=1;i<=n;i++)
{
if(father[i]==i)
{
cnt++;
node t;
t.ft=i;
t.sum=sum[i];
s.push(t);
}
}
if( q<cnt-p || cnt<q ||(m==0&&(cnt-!(p==0)<q )))
cout<<"NO"<<endl;
else
{
cout<<"YES"<<endl;
int res=0;
while(cnt!=q)
{
res++;
cnt--;
node a=s.top();
s.pop();
node b=s.top();
s.pop();
node t;
father[a.ft]=father[b.ft];
long long tep=sum[b.ft]+sum[a.ft]+1+sum[a.ft]+sum[b.ft];
sum[b.ft]=min(inf,tep);
t.ft=father[b.ft];
t.sum=sum[b.ft];
cout<<a.ft<<" "<<b.ft<<endl;
s.push(t);
x=a.ft,y=b.ft;
}
while(res<p)
{
res++;
cout<<x<<" "<<y<<endl;
}
}
return 0;
}