题意:给一张图判断是不是强连通+所有边都在一个圈里
就是判断一张图是不是仙人掌图。
仙人掌图的性质:
1.没有横向边
2.图中没有桥
3.每个点的逆向边和low[v]值比dfn[u]小的子节点v的数量和小于2
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int dfn[20005],low[20005],cnt,n;
bool mark[20005],ans;
vector<int> G[20005];
void Tayjan(int x)
{
dfn[x]=low[x]=cnt++;
int c=0;
for(vector<int>::iterator it=G[x].begin();it!=G[x].end();it++)
{
if(mark[*it]) ans=false;
if(!dfn[*it])
{
Tayjan(*it);
low[x]=min(low[x],low[*it]);
if(low[*it]>dfn[x]) ans=false;
if(low[*it]<dfn[x]) c++;
}
else
{
low[x]=min(low[x],dfn[*it]);
c++;
}
if(c>=2) ans=false;
}
mark[x]=true;
return;
}
void init()
{
memset(mark,0,sizeof(mark));
memset(dfn,0,sizeof(dfn));
ans=true;
cnt=1;
for(int i=0;i<=n;i++)
{
G[i].clear();
}
return;
}
void input()
{
int a,b;
while(scanf("%d%d",&a,&b)!=EOF&&(a||b))
{
G[a].push_back(b);
}
return;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
init();
input();
Tayjan(0);
for(int i=0;i<=n-1;i++) if(!dfn[i]) ans=false;
if(ans) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}