拓扑排序
处理何种问题:虽说是排序,但是主要作用是判断有向图是否有环。
性能:时间复杂度为O(E),E为边的个数。
原理:每次找入度为0的点入栈,然后将与此相连的节点入度减1;重复以上步骤,直到栈中为空。记录弹出节点次数,如果次数与节点总数相同,及无环,否则,有环的存在。(证明的时候注意,如果一个点的入度已变为0,则再也不会有其他点能到达它)
实现步骤:建图(vector)+ 栈(队列) 模拟
备注:略
输入样例解释:
2 2 //n 节点个数,m 边的个数
1 2 //由a 到 b
2 1
3 2
1 2
1 3
输出样例解释:
Cycle //有环
Not Cycle //无环
#include<iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
#include<Stack>
#include<vector>
using namespace std;
const int MaxN=10010;
vector<int>edge[MaxN];
stack<int>S;
int n,m,ctor;
int ind[MaxN];//入度
void init()
{
ctor=0;
memset(ind,0,sizeof(ind));
for(int i=0;i<=n;++i)
{
edge[i].clear();
}
while(!S.empty())
{
S.pop();
}
}
void solve()
{
for(int i=1;i<=n;++i) //节点必须由1开始
{
if(ind[i]==0)
S.push(i);
}
while(!S.empty())
{
int temp=S.top();
S.pop();
++ctor;
int len=edge[temp].size();
for(int i=0;i<len;++i)
{
--ind[edge[temp][i]];
if(ind[edge[temp][i]]==0)
S.push(edge[temp][i]);
}
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
init();
int a,b;
while(m--)
{
scanf("%d%d",&a,&b);
++ind[b];
edge[a].push_back(b);
}
solve();
if(ctor==n)
printf("Not Cycle\n");
else
printf("Cycle\n");
}
return 0;
}

浙公网安备 33010602011771号