思想
用并查集
通过并查集统计一下是否所以点都可以从1到达,是否只有1不是到达点。
#include<bits/stdc++.h>
using namespace std;
int n,m;
const int N=1e5+10;
int p[N],in[N];
int find(int x)
{
if(x!=p[x])x=find(p[x]);
return p[x];
}
void merge(int a,int b)
{
p[find(a)]=find(b);
}
void solve()
{
cin>>n>>m;
//初始化部分
memset(p,0,sizeof p);
memset(in,0,sizeof in);
for(int i=0;i<n;i++)p[i]=i;
//输入部分
for(int i=0;i<m;i++)
{
int u,v;cin>>u>>v;
merge(u,v); //合并
in[v]++; //能到达v的道路数++
}
int count1=0,count0=0; //入度为1的点的个数 入度为0的点的个数
int flag=1;
for(int i=1;i<=n;i++)
{
if(in[i]==0)count0++; //起始点的入度为0,这里统计一下入度为0的点的个数,实际上就是专属起点部分
else if(in[i]==1)count1++; //意味着只有1条路到达我这里
if(find(1)!=find(i))flag=0; //意味着从1无法到达我这里
}
if(flag&&(count1==n-1&&count0==1)) //flag=1意味着从七十点可以到达任何点,那也就意味着可以从任意点到达另一个任意点
{ //count1==n-1是表示入读为1的点有n-1个,缺的那个就是起点,起点没有入边,入度为0 //count0=1表示入度为0的点只有1个,也就是起点
cout<<"YES"<<endl;
}
else
{
cout<<"NO"<<endl;
}
}
int main( )
{
int t=1;cin>>t;
while(t--)
{
solve();
}
return 0;
}