题意:有两堆结点,其中每一堆已分别连上了若干边,要求:①分别在这两堆中同时连上在两堆中都未连上的边 ②不能连出回路,n个结点的一堆至多有n-1条边
想法:n=1000,开俩邻接矩阵,由于无向图,只需判定矩阵的一半,将已有的边标记为1。枚举两个矩阵的这一半,如果两个都是0则说明这条边都没出现过, 将这条边加入集合s,加入的同时别忘了也要将这条边的结点加入并查集中,不然会处理不了回路的情况。
代码如下:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <set>
using namespace std;
const int N = 1010;
int n,g2[N][N],g1[N][N],m,k;
set<pair<int,int>>s1,s2,s;
int p1[N],p2[N];
int find1(int x)
{
if(p1[x]!=x) p1[x]=find1(p1[x]);
return p1[x];
}
int find2(int x)
{
if(p2[x]!=x) p2[x]=find2(p2[x]);
return p2[x];
}
int main()
{
cin>>n>>m>>k;
for(int i=1;i<=n;i++){
p1[i]=i;p2[i]=i;}
int x1=m,x2=k;
while (x1 -- )
{
int x,y;
cin>>x>>y;
if(x<y) swap(x,y);
if(find1(x)!=find1(y)) p1[find1(x)]=find1(y);
g1[x][y]=1;
}
while(x2--)
{
int x,y;
cin>>x>>y;
if(x<y) swap(x,y);
if(find2(x)!=find2(y)) p2[find2(x)]=find2(y);
g2[x][y]=1;
}
for(int i=1;i<=n;i++)
for(int j=1;j<i;j++)
{
if(g1[i][j]==0) s1.insert({
i,j});
if(g2