NO
题目大意:给你一个有向图,判断是否有环。
思路:构建拓扑排序,如果排序失败,说明该有向图存在有向环。
另一种思路,用链式前向星存储图,在数据输入的同时统计每个点的入度,
并存入indegree数组,每删除一个点,就遍历以这个点为起点的边,将边
对应的入度减1即可选择并删除下一点。用队列来存储已发现的入度为0的
点,更新入度的同时更新这个队列。如果最终得到队列中的元素个数小于
总的元素个数,说明排序失败,存在环。
第一种方法:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
int N,M,t;
int topo[110],vis[110],G[110][110];
bool dfs(int u)
{
vis[u] = -1;
for(int v = 0; v < N; v++)
{
if(G[u][v])
{
if(vis[v] < 0)
return false;
else if(!vis[v] && !dfs(v))
return false;
}
}
vis[u] = 1;
topo[--t] = u;
return true;
}
bool toposort()
{
t = N;
memset(vis,0,sizeof(vis));
for(int u = 0; u < N; u++)
if(!vis[u])
if(!dfs(u))
return false;
return true;
}
int main()
{
int a,b;
while(cin >> N >> M)
{
if(!N && !M)
break;
memset(G,0,sizeof(G));
for(int i = 0; i < M; i++)
{
cin >> a >> b;
G[a][b] = 1;
}
if(toposort())
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
}
第二种方法:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 110;
const int MAXM = 110;
int head[MAXN],queue[MAXN],indegree[MAXN],N,M;
struct EdgeNode
{
int to;
int w;
int next;
};
EdgeNode Edges[MAXM];
bool toposort()
{
int iq = 0;
for(int i = 0; i < N; i++)
{
if(indegree[i] == 0)
queue[iq++] = i;
}
for(int i = 0; i < iq; i++)
{
for(int k = head[queue[i]]; k != -1; k = Edges[k].next)
{
indegree[Edges[k].to]--;
if(indegree[Edges[k].to] == 0)
{
queue[iq++] = Edges[k].to;
}
}
}
if(iq == N)
return true;
return false;
}
int main()
{
int x,y;
while(cin >> N >> M)
{
if(!N && !M)
break;
memset(Edges,0,sizeof(Edges));
memset(head,-1,sizeof(head));
memset(indegree,0,sizeof(indegree));
memset(queue,0,sizeof(queue));
for(int i = 0; i < M; i++)
{
cin >> x >> y;
Edges[i].to = y;
Edges[i].w = 1;
Edges[i].next = head[x];
head[x] = i;
indegree[y]++;
}
if(toposort())
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
}
HDU3342 Legal or Not【拓扑排序】【链式前向星】
原文:http://blog.csdn.net/lianai911/article/details/42031407