电力
// 电力.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
/*
https://ac.nowcoder.com/acm/contest/963/F
https://loj.ac/s/2396894
求一个无向图删除一个点之后,联通块最多有多少。
输入描述:
多组数据。第一行两个整数P,C表示点数和边数。
接下来C行每行两个整数p1,p2,表示p1与p2有边连接,保证无重边。读入以0 0结束。
输出描述:
输出若干行,表示每组数据的结果。
3 3
0 1
0 2
2 1
4 2
0 1
2 3
3 1
1 0
0 0
1
2
2
1≤P≤10000,C≥0,0≤p1,p2<P
*/
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 10010, M = 30010;
int h[N], e[M], ne[M], idx;
int dfn[N], low[N], timestamp;
int n, m, root;
int ans;
void add(int a, int b) {
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
void tarjan(int u) {
dfn[u] = low[u] = ++timestamp;
int flag = 0; int cnt = 0;
for (int i = h[u]; i != -1; i = ne[i]) {
int k = e[i];
if (!dfn[k]) {
tarjan(k);
low[u] = min(low[u], low[k]);
if (low[k] >= dfn[u]) {
cnt++;
}
}
else {
low[u] = min(low[u], dfn[k]);
}
}
if (root != u) cnt++;
ans = max(ans, cnt);
}
void solve() {
for (int i = 0; i < m; i++) {
int a, b; cin >> a >> b;
if (a == b) continue;
add(a, b); add(b, a);
}
int cnt = 0;
for (int i = 0; i < n; i++) {
if (!dfn[i]) {
root = i; cnt++;
tarjan(root);
}
}
cout << cnt + ans - 1 << endl;
}
int main()
{
while (1) {
cin >> n >> m; if (n + m == 0) break;
memset(h, -1, sizeof h);
memset(dfn, 0, sizeof dfn);
memset(low, 0, sizeof low);
idx = 0; timestamp = 0; root = -1; ans = 0;
solve();
}
return 0;
}
作 者: itdef
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力

