唯一需要注意的是1.2.3.4是有先后顺序的。考虑把(ai, bi)看做一条边,于是一个n个点的连通块最多只能连n条边,如果顺序是1.3.2.4那么是显然的并查集。但是1.2.3.4的话我们就需要确认每个点到底有没有被用。
把没被占用的点作为连通块的根,这样就能定位到没被用的点了。这道题需要用快读,不用的话会超时只有50分
#include<bits/stdc++.h>
using namespace std;
const int maxn=300005;
int n,m;
bool vis[maxn];
int fa[maxn];
int find(int x)
{
return x==fa[x]?x:fa[x]=find(fa[x]);
}
void merge(int A,int B)
{
fa[find(A)]=find(B);
}
bool same(int A,int B)
{
return find(A)==find(B);
}
int read()
{
int x=0;
char ch=getchar();
bool flag=false;
while(ch<'0' || ch>'9')
{
if(ch=='-')
flag=true;
ch=getchar();
}
while(ch>='0' && ch<='9')
{
x=(x<<3)+(x<<1)+(ch^'0');
ch=getchar();
}
return flag?-x:x;
}
int main()
{
m=read(),n=read();
for(int i=1;i<=n;i++)
fa[i]=i;
for(int i=1;i<=m;i++)
{
int A=read(),B=read();
bool ok=true;
if(!vis[A])
{
vis[A]=true;
merge(A,B);
}
else if(!vis[B])
{
vis[B]=true;
merge(B,A);
}
else if(!vis[find(A)])
{
vis[find(A)]=true;
merge(A,B);
}
else if(!vis[find(B)])
{
vis[find(B)]=true;
merge(B,A);
}
else ok=false;
puts(ok?"SUCCESS":"FAILED");
}
return 0;
}