割点

发布 : 2020-06-25 分类 : Tarjan 浏览 :

题目描述

给定一个有 N 个点的无向连通图,问图中哪些点去掉后图将不再连通?同时输出去掉这个点后,图被分为几个连通块?

输入包含多组数据,每组以 0 结尾,每行描述图中边的两个顶点的标号。每组数据之间有一个空行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

struct Edge{
int tar;
Edge * next;
} * first[1000], * eg, edges[1000000];
int fl[1000];
void addedge(int a, int b){
eg->tar = b;
eg->next = first[a];
first[a] = eg++;
}
void dfs(int k, int x){
fl[k] = x;
for(Edge * arr = first[k]; arr != NULL; arr = arr->next){
if(arr->tar == x || fl[arr->tar] == x)
continue;
dfs(arr->tar, x);
}
}
int main(){
int cas = 0;
while(true){
memset(first, 0, sizeof(first));
eg = edges;
int n = 0;
while(true){
int a, b;
cin >> a;
if(!a) break;
cin >> b;
n = max(n, max(a, b));
a--; b--;
addedge(a, b);
addedge(b, a);
}
if(!n) return 0;
if(cas) cout << endl;
cas++;
cout << "Network #" << cas << endl;
bool f = false;
memset(fl, -1, sizeof(fl));
for(int i = 0; i < n; i++){
if(first[i] == NULL)
continue;
int cnt = 0;
for(int j = 0; j < n; j++){
if(i == j) continue;
if(first[j] == NULL) continue;
if(fl[j] < i){
cnt++;
dfs(j, i);
}
}
if(cnt > 1){
cout << "SPF node " << i+1 << " leaves " << cnt << " subnets" << endl;
f = true;
}
}
if(!f) cout << "No SPF nodes" << endl;
}
return 0;
}
/*
Input:
1 2
5 4
3 1
3 2
3 4
3 5
0
Output:
Network #1
SPF node 3 leaves 2 subnets
Input:
0
(end)
*/

本文作者 : preccrep
原文链接 : https://preccrep.github.io/2020/06/25/%E5%89%B2%E7%82%B9/
版权声明 : 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
留下足迹

博客已萌萌哒运行(●'◡'●)ノ♥
Theme - BMW | Made With 💗 | Powered by GodBMW