码迷,mamicode.com
首页 > 其他好文 > 详细

Luogu 2812 校园网络 - Tarjan

时间:2018-09-11 21:06:17      阅读:179      评论:0      收藏:0      [点我收藏+]

标签:\n   none   getch   ns2   printf   ==   ||   sed   opened   

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\n", ans1);
76     if(col_num == 1) return printf("0\n"), 0;
77     for(int i = 1; i <= col_num; ++i)
78         if(!chu[i]) ans2++;
79     printf("%d\n", max(ans1, ans2));
80 }
View Code

 

Luogu 2812 校园网络 - Tarjan

标签:\n   none   getch   ns2   printf   ==   ||   sed   opened   

原文地址:https://www.cnblogs.com/cychester/p/9629789.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!