将两边集合叠加以某一个点为中心团去增加点,形成了以该点为中心的团,随后再分开,对两边的团进行枚举。
群友的想法很棒qwq
#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef pair<int,int>PII;
const int N=1e5+7;
int f1[N],f2[N];
int n,m1,m2;
vector<PII>ans;
int find(int x,int p[])
{
if(x!=p[x])p[x]=find(p[x],p);
return p[x];
}
int main()
{
cin>>n>>m1>>m2;
for(int i=1;i<=n;i++)f1[i]=f2[i]=i;
int x,y;
while(m1--)
{
cin>>x>>y;
x=find(x,f1),y=find(y,f1);
if(x!=y)f1[x]=y;
}
while(m2--)
{
cin>>x>>y;
x=find(x,f2),y=find(y,f2);
if(x!=y)f2[x]=y;
}
for(int i=1;i<=n;i++)
{
int x=find(1,f1),y=find(i,f1),a=find(1,f2),b=find(i,f2);
if(x!=y&&a!=b)
{
f1[x]=y;
f2[a]=b;
ans.push_back({i,1});
}
}
vector<int>l,r;
for(int i=2;i<=n;i++)
{
if(find(1,f1)!=find(i,f1)&&find(i,f1)==i&&find(1,f2)==find(i,f2))l.push_back(i);
if(find(1,f2)!=find(i,f2)&&find(i,f2)==i&&find(1,f1)==find(i,f1))r.push_back(i);
}
cout<<ans.size()+min(l.size(),r.size())<<endl;
for(int i=0;i<ans.size();i++)
cout<<ans[i].x<<' '<<ans[i].y<<endl;
for(int i=0;i<min(l.size(),r.size());i++)
cout<<l[i]<<' '<<r[i]<<endl;
}