1 // 给你一个有向图,问你最少加几条边能使得该图强连通
2 #include <iostream>
3 #include <cstdio>
4 #include <cstring>
5 #include <string>
6 #include <utility>
7 #include <algorithm>
8 #include <vector>
9 #include <queue>
10 #include <stack>
11 using namespace std;
12 #define max(x,y) x>=y?x:y
13 #define lowbit(x) x&(-x)
14 typedef long long ll;
15 const int N=20010;
16 int n,m;
17 int head[N],low[N],num[N];
18 int in[N],out[N],be[N];
19 int ans,cnt,ans1,ans2;
20 int index;
21 bool vis[N];
22 struct Edge
23 {
24 int from,to,nex;
25 }e[N*6];
26 stack<int>s;
27 void init()
28 {
29 memset(head,-1,sizeof(head));
30 memset(num,-1,sizeof(num));
31 memset(vis,0,sizeof(vis));
32 memset(low,0,sizeof(low));
33 memset(in,0,sizeof(in));
34 memset(out,0,sizeof(out));
35 cnt=index=0;
36 }
37 void add(int u,int v)
38 {
39 e[cnt].from=u;
40 e[cnt].to=v;
41 e[cnt].nex=head[u];
42 head[u]=cnt++;
43 }
44 void tarjan(int u)
45 {
46 low[u]=num[u]=++index;
47 vis[u]=1;
48 s.push(u);
49 for (int i=head[u];i!=-1;i=e[i].nex)
50 {
51 int v=e[i].to;
52 if(num[v]==-1)
53 {
54 tarjan(v);
55 low[u]=min(low[u],low[v]);
56 }
57 else if(vis[v])
58 {
59 low[u]=min(low[u],num[v]);
60 }
61 }
62 if(num[u]==low[u])
63 {
64 int x;
65 ans++;
66 do{
67 x=s.top();
68 s.pop();
69 vis[x]=0;
70 be[x]=ans;
71 }while(x!=u);
72 }
73 }
74 int main()
75 {
76 while(~scanf("%d %d",&n,&m))
77 {
78 init();
79 ans=0;
80 int a,b;
81 for (int i=0;i<m;i++)
82 {
83 scanf("%d %d",&a,&b);
84 add(a,b);
85
86 }
87 for (int i=1;i<=n;i++)
88 {
89 if(num[i]==-1)
90 {
91 tarjan(i);
92 }
93 }
94 for (int i=0;i<cnt;i++)
95 {
96 int a=e[i].from;
97 int b=e[i].to;
98 if(be[a]!=be[b])
99 {
100 in[be[b]]++;
101 out[be[a]]++;
102 }
103 }
104 ans1=ans2=0;
105 for (int i=1;i<=ans;i++)//ans 从1开始。ans为原图强联通分量的个数、
106 {
107 if(!in[i])
108 {
109 ans1++;
110 }
111 if(!out[i])
112 {
113 ans2++;
114 }
115 }
116 printf("%d\n",ans==1?0:max(ans1,ans2));
117 }
118 return 0;
119 }
120
121 /*
122
123 3 2
124 1 2
125 2 3
126
127 有3个联通快
128
129 */