Upload
Upload
Upload
唯一需要注意的是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;
}

相关文章: