#include<vector>
#include<iostream>
using namespace std;
#define M 10
int dfn[M],low[M];
int STACK[M],top,num;//stack模拟堆栈,//num表示强联通分量的个数
int din;//这个是时间戳
int in[M];//是否在堆栈中
vector<int>Edge[M];//邻接表,表示是否相邻
int n,m;
int min(int a,int b)
{
return a=a<b?a:b;
}
void tanj(int a)
{
int j,i;
in[a]=1;//标记访问过
din++;
dfn[a]=low[a]=din;//标记时间戳
STACK[++top]=a;//压入堆栈
for(i=0;i<Edge[a].size();i++)
{
j=Edge[a][i];//取下一个顶点
if(!dfn[j])//如果下一个点没有标记过(树枝边)
{
tanj(j);//访问下一个节点,这样可以算出来low[j],用来下一步求
low[a]=min(dfn[a],low[j]);//更新low
}
else if(in[j])//如果下一个点被访问过,而且在堆栈中(也就是向后边)(向后边的定义就是指向栈中节点)
{
low[a]=min(dfn[a],dfn[j]);//更新low
}
}
if(dfn[a]==low[a])
{
num++;
do
{
j=STACK[top--];//出栈
in[j]=0;//标记不在堆栈中
}while(j!=a);
}
}
void init()
{
int i;
top=0;
num=0;
din=0;
memset(dfn,0,sizeof(dfn));
for(i=1;i<=n;i++)
{
if(!dfn[i])
{
tanj(i);
}
}
}
int main()
{
int i,a,b;
freopen("input.txt","r",stdin);
while(cin>>n>>m ,n+m)
{
for(i=1;i<=n;i++)
{
Edge[i].clear();
}
for(i=0;i<m;i++)
{
cin>>a>>b;
Edge[a].push_back(b);
}
init();
if(num==1)
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
}
return 0;
}
/*
1 这里是采用链式存储结构。利用vector<int>来存储邻接边
*/
hdoj1269 Tarjan
最新推荐文章于 2022-08-03 14:07:24 发布