题解
- 其实这题可以转换为求出有多少个点不在环内
- 容易想到拓扑排序
- 拓扑排序的做法:
- 每次加入没有入度的点,在将与它相连的边删去
- 那么能被删去的点,其实就是不在环内的点
代码
1 #include<cstdio>
2 #include<iostream>
3 #include<algorithm>
4 #include<cmath>
5 #include<cstring>
6 using namespace std;
7 struct edge{ int to,from; }e[1000010];
8 int n,m,head,tail,ans,k[1000010],d[1000010],cnt,last[1000010];
9 void insert(int x,int y) { d[y]++; e[++cnt].to=y; e[cnt].from=last[x]; last[x]=cnt; }
10 int main()
11 {
12 freopen("mikado.in","r",stdin);
13 freopen("mikado.out","w",stdout);
14 scanf("%d%d",&n,&m);
15 for (int i=1;i<=m;i++)
16 {
17 int x,y;
18 scanf("%d%d",&x,&y);
19 insert(x,y);
20 }
21 head=1; tail=0;
22 for (int i=1;i<=n;i++)
23 if (d[i]==0)
24 k[++tail]=i;
25 while (head<=tail)
26 {
27 int u=k[head]; head++;
28 ans++;
29 for (int i=last[u];i;i=e[i].from)
30 {
31 d[e[i].to]--;
32 if (d[e[i].to]==0) k[++tail]=e[i].to;
33 }
34 }
35 printf("%d",ans);
36 return 0;
37 }