5.5 Day1

拓扑判环

相比于tarjan判环来说,拓扑判环有较小的常数,写起来也较方便
对于环上的所有点来说,它们的入度肯定大于0,那么拓扑判环就是利用这一性质来做。算法不断重复以下步骤:找到入度为0的点,把与它相连的所有点的入度减一,然后这个点入队。最后,没有入过队的点,就是环上的点。
拓扑判环,只能判断是否有环,哪些点在环上,却不能判断有几个环,哪些点属于一个环。这是要注意的地方。
代码:
 #include <bits/stdc++.h>
using namespace std;
const int N=1e5+5,M=2e5+5;
int n,m,u,v;
int du[N];
int cnt,head[N];
struct edge{int next,to;}e[M];

inline void add(int u,int v)
{
	cnt++;
	e[cnt].next=head[u];
	e[cnt].to=v;
	head[u]=cnt;	
}

int main(){
	scanf("%d%d",&n,&m);
	for (register int i=1; i<=m; ++i) scanf("%d%d",&u,&v),add(u,v),du[v]++;
	
	cnt=0;
	queue<int>q;
	for (register int i=1; i<=n; ++i) if (!du[i]) q.push(i),cnt++;
	while (!q.empty())
	{
		int u=q.front(); q.pop();
		for (register int i=head[u]; i; i=e[i].next)
		{
			du[e[i].to]--;
			if (!du[e[i].to]) q.push(e[i].to),cnt++;	
		}
	}
	
	printf("%d\n",cnt);   // cnt记录不在环上的点 
	if (cnt==n) puts("YES"); else puts("NO");
return 0;	
}                              

猜你喜欢

转载自blog.csdn.net/Dove_xyh/article/details/89889002
5.5