pku 2117 tarjan算法求割点

http://poj.org/problem?id=2117

给出一个森林,求删掉一个点后,形成的连通块的个数。和pku1523一样的意思,只不过这里是森林了。。还要加上原来的连通块数。

注意:这里的当m == 0 时要单独考虑,因为要删掉一个点,所以== n-1 而单纯的求的话是n了。。。

View Code
#include <cstdio>
#include <cstring>
#include <iostream>
#define maxn 10010
using namespace std;
struct node
{
int v;
int next;
}g[4*maxn];
int low[maxn],dfn[maxn],cut[maxn],head[maxn];
int t,index,n;
int root,rtson,ans;
void add(int u,int v)
{
g[t].v = v;
g[t].next = head[u];
head[u] = t++;
}
void init()
{
memset(g,0,sizeof(g));
for (int i = 0;i < maxn; ++i)
{
head[i] = low[i] = dfn[i] = cut[i] = 0;
}
t = 1;
index = ans = 0;
}
void tarjan(int i)
{
int j,k;
low[i] = dfn[i] = ++index;
for (k = head[i]; k; k = g[k].next)
{
j = g[k].v;
if (!dfn[j])
{
tarjan(j);
if (i == root) rtson++;
else
{
if (low[i] > low[j]) low[i] = low[j];
if (low[j] >= dfn[i]) cut[i]++;
}
}
else
{
if(low[i] > dfn[j])
low[i] = dfn[j];
}
}
ans = max(ans,cut[i]);
}
void solve()
{
int count = 0;
for (int i = 0; i < n; ++i)
{
root = i;
rtson = 0;
if (!dfn[root])
{
count++;
tarjan(root);
}
cut[root] = rtson - 1;
ans = max(cut[root],ans);
}
printf("%d\n",ans + count);
}
int main()
{
int m,i,x,y;
while (cin>>n>>m)
{
if (!n && !m) break;
if (m == 0)
{
printf("%d\n",n-1);
continue;
}
init();
for (i = 0; i < m; ++i)
{
cin>>x>>y;
add(x,y); add(y,x);
}
solve();
}
}



posted @ 2012-02-13 15:14  E_star  阅读(270)  评论(0编辑  收藏  举报