题目链接:https://vjudge.net/contest/236513#problem/E
大意:给你n条边的关系,输入的第一个只指向第一个,然后让你判断要想从指定的点到达剩下的所有的点,问你最少需要添加多少条边才符合要求。
思路:首先使用tarjan算法进行染色,缩点。到最后判断 缩减后 入度为零的不含有城市中心的强连通子图的个数就可以了!!!
原因,染完色之后,如果有入度为0的强连通子图,那么这个点就可能符合,然后吧满足这些条件的记录一下。注意,在累加 的时候,不能将入度为0的含有城市中心的强连通子图计算在内,因为这个图中,有城市中心的强连通图中,这个图中的其他所有的点都能由城市中心到达,所以不用累加。
代码如下:
1 #include<iostream>
2 #include<string>
3 #include<cstring>
4 #include<cmath>
5 #include<algorithm>
6 #include<map>
7 #include<vector>
8 #include<stack>
9 #include<queue>
10 using namespace std;
11 # define maxn 5005
12 vector<int >wakaka[maxn];
13 map<int,int>p;
14 stack<int>q;
15 int dfn[maxn],low[maxn],vis[maxn];
16 int out[maxn],cnt[maxn],color[maxn],in[maxn];
17 int num,ans;
18 void tarjan(int u)
19 {
20 vis[u]=1;
21 q.push(u);
22 low[u]=dfn[u]=++num;
23 int len=wakaka[u].size();
24 for(int i=0; i<len; i++)
25 {
26 int v=wakaka[u][i];
27 if(vis[v]==0)
28 {
29 tarjan(v);
30 low[u]=min(low[u],low[v]);
31 }
32 if(vis[v]==1)
33 {
34 low[u]=min(low[u],dfn[v]);
35 }
36 }
37 if(low[u]==dfn[u])
38 {
39 ans++;
40 int top;
41 do
42 {
43 top=q.top();
44 q.pop();
45 vis[top]=-1;
46 color[top]=ans;
47 }
48 while(top!=u);
49 }
50 }
51 int main()
52 {
53 int n,m,t;
54 while(cin>>n>>m>>t)
55 {
56 num=ans=0;
57 memset(vis,0,sizeof(vis));
58 memset(cnt,0,sizeof(cnt));
59 memset(out,0,sizeof(out));
60 memset(in,0,sizeof(in));
61 memset(color,0,sizeof(color));
62 while(!q.empty())q.pop();
63 for(int i=1; i<=n; i++)
64 {
65 wakaka[i].clear();
66 }
67 p.clear();
68 for(int i=1; i<=m; i++)
69 {
70 int u,v;
71 cin>>u>>v;
72 p[u]++;
73 p[v]++;
74 wakaka[u].push_back(v);
75 }
76 for(int i=1; i<=n; i++)
77 {
78 if(vis[i]==0)
79 tarjan(i);
80 }
81 //cout<<color[1]<<endl<<color[2]<<endl;
82 for(int i=1; i<=n; i++)
83 {
84 int len=wakaka[i].size();
85 for(int j=0; j<len; j++)
86 {
87 if(color[i]!=color[wakaka[i][j]])
88 {
89 in[color[i]]++;
90 out[color[wakaka[i][j]]]++;
91 }
92 }
93 cnt[color[i]]++;
94 }
95 int t1=0,t2=0;
96 for(int i=1; i<=ans; i++)
97 {
98 if(in[i]==0)
99 t1++;
100 if(out[i]==0&&i!=color[t])
101 {
102 t2++;
103 }
104 }
105 cout<<t2<<endl;
106 //else {
107 //cout<<max(t1,t2)<<endl;
108 //}
109 //}
110 }
111 return 0;
112 }
113
114