题目描述
给定一个有向图,判断该有向图是否存在一个合法的拓扑序列。
输入
输入包含多组,每组格式如下。
第一行包含两个整数n,m,分别代表该有向图的顶点数和边数。(n<=10)
后面m行每行两个整数a b,表示从a到b有一条有向边。
输出
若给定有向图存在合法拓扑序列,则输出YES;否则输出NO。
示例输入
1 0
2 2
1 2
2 1
示例输出
YES
NO
#include <cstdio>
#include <cstring>
using namespace std;
bool mapp[15][15];
int vis[30];
int n;
int dfs(int x)
{
vis[x]=-1; //表示该点正在被访问
for(int i=1; i<=n; i++)
{
if(mapp[x][i]) //遍历邻接点
{
if(vis[i]==-1) //如果成环则返回false
return false;
else if(!vis[i]&&!dfs(i)) //如果没被访问过且以下一个点为起点的图存在环则返回false
return false;
}
}
vis[x]=1; //表示已被访问过
return true;
}
int ok()
{
for(int i=1; i<=n; i++)
if(!vis[i]) //遍历每一个点防止整个图有多个连通图
if(!dfs(i)) //如果以该点为起点的图含有环则返回false
return false;
return true;
}
int main()
{
int m;
while(~scanf("%d %d",&n,&m))
{
memset(mapp,0,sizeof(mapp));
memset(vis,0,sizeof(vis));
int x,y;
for(int i=0; i<m; i++)
{
scanf("%d %d",&x,&y);
mapp[x][y]=true;
}
if(ok())
printf("YES\n");
else
printf("NO\n");
}
}
#include <cstdio>
#include <cstring>
using namespace std;
bool mapp[15][15];
int vis[30];
int n;
int dfs(int x)
{
vis[x]=-1; //表示该点正在被访问
for(int i=1; i<=n; i++)
{
if(mapp[x][i]) //遍历邻接点
{
if(vis[i]==-1) //如果成环则返回false
return false;
else if(!vis[i]&&!dfs(i)) //如果没被访问过且以下一个点为起点的图存在环则返回false
return false;
}
}
vis[x]=1; //表示已被访问过
return true;
}
int ok()
{
for(int i=1; i<=n; i++)
if(!vis[i]) //遍历每一个点防止整个图有多个连通图
if(!dfs(i)) //如果以该点为起点的图含有环则返回false
return false;
return true;
}
int main()
{
int m;
while(~scanf("%d %d",&n,&m))
{
memset(mapp,0,sizeof(mapp));
memset(vis,0,sizeof(vis));
int x,y;
for(int i=0; i<m; i++)
{
scanf("%d %d",&x,&y);
mapp[x][y]=true;
}
if(ok())
printf("YES\n");
else
printf("NO\n");
}
}