您的位置:首页 > 其它

poj - 1144 - Network(连通分量)

2013-07-27 01:26 316 查看
题意:求一个无向图的割顶(点)。

题目链接:http://poj.org/problem?id=1144

——>>low[i]为i和i的后代能连到dfs中层次最浅的结点,对于一个结点u,如果u不是根且low[u] >= pre[u],或者u是根且u的”孩子“(与根相连的点数减去其反向边数)不只1个,则u是割顶(点)。

#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxn = 100 + 10;
int pre[maxn], low[maxn], N, dfs_clock;
bool iscut[maxn];
vector<int> G[maxn];

void init()
{
dfs_clock = 0;
memset(pre, 0, sizeof(pre));
memset(iscut, 0, sizeof(iscut));
}

int dfs(int u, int fa)
{
int lowu = pre[u] = ++dfs_clock, child = 0;
int cnt = G[u].size();
for(int i = 0; i < cnt; i++)
{
int v = G[u][i];
if(!pre[v])
{
child++;
int lowv = dfs(v, u);
lowu = min(lowu, lowv);
if((u == 1 && child > 1) || (u != 1 && pre[u] <= low[v])) iscut[u] = 1;
}
else if(pre[v] < pre[u] && v != fa) lowu = min(lowu, pre[v]);
}
return low[u] = lowu;
}

int main()
{
int u, v, i;
while(scanf("%d", &N) == 1 && N)
{
for(i = 1; i <= N; i++) G[i].clear();
while(scanf("%d", &u) == 1 && u)
{
while(getchar() != '\n')
{
scanf("%d", &v);
G[u].push_back(v);
G[v].push_back(u);
}
}
init();
dfs(1, -1);
int cnt = 0;
for(i = 1; i <= N; i++) if(iscut[i]) cnt++;
printf("%d\n", cnt);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: