Electricity
题目大意
给定一个 个点、 条边的无向图,试求从图中删去一个点后,图中最多有多少个连通分量。
数据范围:
解题思路
首先要明白这题不是要你找割点,而是求图中删去一个点后,图中最多有多少个连通分量。
图中删去一个点后,图中连通分量个数 连通子图个数() 。
设 为删去点 后,图中可以产生的连通分量。
判断条件
if (low[v] >= dfn[u])
{
flag++;
if((u != rt || flag > 1)) cut[u]++;
}
AC CODE
#include <bits/stdc++.h>
using namespace std;
struct Fastio
{
template <typename T>
inline Fastio operator>>(T &x)
{
x = 0;
char c = getchar();
while (c < '0' || c > '9')
c = getchar();
while (c >= '0' && c <= '9')
x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
return *this;
}
inline Fastio &operator<<(const char *str)
{
int cur = 0;
while (str[cur])
putchar(str[cur++]);
return *this;
}
template <typename T>
inline Fastio &operator<<(T x)
{
if (x == 0)
{
putchar('0');
return *this;
}
if (x < 0)
putchar('-'), x = -x;
static int sta[45];
int top = 0;
while (x)
sta[++top] = x % 10, x /= 10;
while (top)
putchar(sta[top] + '0'), --top;
return *this;
}
} io;
int n, m, rt, ans, cnt_node, cntn;
int cnt;
array<int, 2000005> head;
struct abc
{
int to, nxt;
};
array<abc, 2000005> dd;
array<int, 2000005> dfn, low, cut;
inline void add(int u, int v)
{
dd[++cnt].to = v;
dd[cnt].nxt = head[u];
head[u] = cnt;
}
inline void tarjan(int u)
{
dfn[u] = low[u] = ++cnt_node;
int flag = 0;
for (int e = head[u]; e; e = dd[e].nxt)
{
int v = dd[e].to;
if (!dfn[v])
{
tarjan(v);
low[u] = min(low[v], low[u]);
if (low[v] >= dfn[u])
{
flag++;
if ((u != rt || flag > 1))
cut[u]++;
}
}
else
low[u] = min(low[u], dfn[v]);
}
}
void init()
{
cnt = 0;
cnt_node = 0;
cntn = 0;
ans = 0;
head.fill(0);
cut.fill(0);
dfn.fill(0);
low.fill(0);
}
signed main()
{
while (1)
{
init();
io >> n >> m;
if (!n && !m)
break;
for (int i = 1; i <= m; ++i)
{
int u, v;
io >> u >> v;
u++;
v++;
add(u, v);
add(v, u);
}
for (int i = 1; i <= n; ++i)
if (!dfn[i])
{
tarjan(rt = i);
cntn++;
}
for (int i = 1; i <= n; ++i)
ans = max(ans, cntn + cut[i]);
io << ans << "\n";
}
return 0;
}
本文来自博客园,作者:蒟蒻orz,转载请注明原文链接:https://www.cnblogs.com/orzz/p/18122147