题目:CF771A Bear and Friendship Condition
并查集-图论-BFS
题目大意
给出一张无向图,对于每一个点三元组 x , y , z x,y,z x,y,z ,若 ( x , y ) (x,y) (x,y) ( y , z ) (y,z) (y,z) 之间分别都有连边,那么 ( x , z ) (x,z) (x,z) 之间也必须有连边
对于给出的无向图,求出该图是否满足要求
观察上面规则的性质,我们发现对于 由一个点三元组组成的连通块,要满足上面要求,必须每两个点之间都有一条连边,也就是满足该连通块是一个完全图
完全图的其中一个判定方法,就是判断一下方程是否成立:
n
(
n
−
1
)
2
=
m
\frac{n(n-1)}{2}=m
2n(n−1)=m (
n
n
n为点数,
m
m
m为变数)
由此,题目就被我们转换成了:对于给出的无向图,求出该图所有连通块是否满足完全图性质
代码:
#include<cstdio>
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
const long long Maxn=150000+20,inf=0x3f3f3f3f;
vector <long long> e[Maxn];
bool vis[Maxn];
long long n,m;
inline long long read()
{
long long s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0' && ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
return s*w;
}
bool bfs(long long s)
{
queue <long long> q;
vis[s]=1,q.push(s);
long long cnt=0,tot=0;
while(q.size())
{
long long x=q.front();
q.pop();
++cnt;
for(long long i=0;i<e[x].size();++i)
{
long long y=e[x][i];
++tot;
if(vis[y])continue;
vis[y]=1,q.push(y);
}
}
if(cnt==1)return 1;
tot>>=1;
return ((cnt*(cnt-1))>>1) == tot;
}
int main()
{
//freopen("in.txt","r",stdin);
n=read(),m=read();
for(long long i=1;i<=m;++i)
{
long long x=read(),y=read();
e[x].push_back(y);
e[y].push_back(x);
}
bool flag=1;
for(long long i=1;i<=n;++i)
{
if(vis[i])continue;
flag=(flag & bfs(i));
if(!flag)break;
}
if(flag)puts("YES");
else puts("NO");
return 0;
}