首先,使用并查集和优先队列,其次,注意价值的增加量取较小值,再者,几个判断no的情况。
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#include <vector>
#include <map>
#include <string>
#include <iostream>
//#include <stdlib.h>
#include <deque>
//#include <windows.h>
using namespace std;
bool flg[100010]={0};//保存没有连通块的单点
long long xxx[100010];//保存路
long long yyy[100010];//保存路
long long value[100010];//保存价值
long long father[100010]={0};//并查集
long long realansx[100010]={0};//答案
long long realansy[100010]={0};long long top=0;//答案
long long a=0,n=0;
struct node
{
long long sum;
long long pot;
bool operator<(const struct node &a) const
{
return sum>a.sum;
}
}tt0,tt1,inf[100010]={0};
priority_queue<node>queues;
long long getf(long long x)//并查集
{
if(father[x]==x) return x;
return father[x]=getf(father[x]);
}
void add(long long a,long long b)//并查集
{
b=getf(b);
a=getf(a);
if(a!=b)
father[a]=b;
}
int main()
{
long long i,j,k,l,t,m,p,q,a,b,c,f,kuaishu=0;
long long xs=0,ys=0,qqq=1000000000,ddd;
scanf("%lld",&n);scanf("%lld",&m);
scanf("%lld",&p);scanf("%lld",&q);
while(!queues.empty()) queues.pop();
for(i=0;i<=n;i++) father[i]=i;
for(i=0;i<m;i++)
{
scanf("%lld",&a);scanf("%lld",&b);scanf("%lld",&c);
add(a,b);
xxx[i]=a;yyy[i]=b;value[i]=c;
flg[a]=1;flg[b]=1;
}
for(i=0;i<m;i++)
{
inf[getf(xxx[i])].pot=getf(xxx[i]);
inf[getf(xxx[i])].sum+=value[i];
}
for(i=1;i<=n;i++)
{
if(inf[i].pot==i)
{
queues.push(inf[i]);
kuaishu++;
}
else if(flg[i]==0)
{
inf[i].pot=i;
inf[i].sum=0;
queues.push(inf[i]);
kuaishu++;
}
}
if(kuaishu-q>p)
{
printf("NO");return 0;
}
if(q>kuaishu)
{
printf("NO");return 0;
}
top=0;
for(i=q;i<kuaishu;i++)
{
p--;
tt0=queues.top();
queues.pop();
tt1=queues.top();
queues.pop();
add(tt0.pot,tt1.pot);
realansx[top]=tt0.pot;realansy[top]=tt1.pot;top++;
tt0.pot=getf(tt0.pot);
tt0.sum+=tt1.sum;
tt0.sum+=min(qqq,tt0.sum+1);
queues.push(tt0);
}
for(j=1;j<=n;j++)
{
if(getf(j)!=j)
{
xs=j;ys=getf(j);
break;
}
}
if(q>kuaishu)
{
printf("NO");return 0;
}
for(i=0;i<p;i++)
{
realansx[top]=xs;realansy[top]=ys;top++;
if(xs==0&&ys==0)
{
printf("NO");return 0;
}
}
printf("YES\n");
for(i=0;i<top;i++)
printf("%lld %lld\n",realansx[i],realansy[i]);
return 0;
}