Luogu 2812 校园网络 - Tarjan

Posted cychester

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu 2812 校园网络 - Tarjan相关的知识,希望对你有一定的参考价值。

Description

给出一个有向图, 要求出至少从哪几个点出发, 能不漏地经过所有节点。

再求出至少加几条边, 才能使图变成一个强联通分量

Solution

求出所有强联通分量, 形成一个有向无环图, 第一问题就是求出有多少强联通分量的入度为 $0$ 

第二个问题就是求出 入度为$0 $和 出度为$0$  的强联通分量的数量  的 最大值, 想象一下就可以了。

在整个图都是强联通分量下, 第二个问题答案为 $0$。

Code

技术分享图片
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define rd read()
 5 #define rep(i,a,b) for(int i = (a); i <= (b); ++i)
 6 #define per(i,a,b) for(int i = (a); i >= (b); --i)
 7 using namespace std;
 8 
 9 const int N = 10500;
10 const int M = 6e6;
11 
12 int head[N], tot;
13 int col[N], col_num, size[N];
14 int n, dfn[N], low[N], cnt, vis[N];
15 int st[N], tp, ans1, ans2;
16 int chu[N], ru[N];
17 
18 struct edge {
19     int nxt, to, fr;
20 }e[M];
21 
22 int read() {
23     int X = 0, p = 1; char c = getchar();
24     for(; c > 9 || c < 0; c = getchar()) if(c == -) p = -1;
25     for(; c >= 0 && c <= 9; c = getchar()) X = X * 10 + c - 0;
26     return X * p;
27 }
28 
29 void add(int u, int v) {
30     e[++tot].to = v;
31     e[tot].nxt = head[u];
32     e[tot].fr = u;
33     head[u] = tot;
34 }
35 
36 void tarjan(int u) {
37     dfn[u] = low[u] = ++cnt;
38     st[++tp] = u;
39     vis[u] = 1;
40     for(int i = head[u]; i; i = e[i].nxt) {
41         int nt = e[i].to;
42         if(!dfn[nt]) tarjan(nt), low[u] = min(low[u], low[nt]);
43         else if(vis[nt]) low[u] = min(low[u], dfn[nt]);
44     }
45     if(dfn[u] == low[u]) {
46         col_num++;
47         for(; tp;) {
48             int nt = st[tp--];
49             vis[nt] = 0;
50             col[nt] = col_num;
51             if(nt == u) break;
52         }
53     }
54 }
55 
56 int main()
57 {
58     n = rd;
59     for(int i = 1; i <= n; ++i) {
60         for(; ;) {
61             int x = rd;
62             if(!x) break;
63             add(i, x);
64         }
65     }
66     for(int i = 1; i <= n; ++i) 
67         if(!dfn[i]) tarjan(i);
68     for(int i = 1; i <= tot; ++i) {
69         int x = e[i].fr, y = e[i].to;
70         if(col[x] == col[y]) continue;
71         ru[col[y]]++; chu[col[x]]++;
72     }
73     for(int i = 1; i <= col_num; ++i) 
74         if(!ru[i]) ans1++;
75     printf("%d
", ans1);
76     if(col_num == 1) return printf("0
"), 0;
77     for(int i = 1; i <= col_num; ++i)
78         if(!chu[i]) ans2++;
79     printf("%d
", max(ans1, ans2));
80 }
View Code

 

以上是关于Luogu 2812 校园网络 - Tarjan的主要内容,如果未能解决你的问题,请参考以下文章

P2812 校园网络(tarjan缩点)

luogu2746 [USACO5.3]校园网Network of Schools [tarjan 缩点]

luogu P1262 间谍网络

P2812 校园网络

[luogu1262]间谍网络

luogu3387 模板缩点 [tarjan 缩点]