您的位置:首页 > 其它

UVA 315 Network(无向图求割点)

2015-08-10 17:49 260 查看
题目大意:
给你一个无向图,求其中割点的个数目。
输入数据
第一行一个 n 代表有 n 个点
接下来有多行,一直到读入一个 0,算整个地图的读入结束,再读入一个0,文件数据结束。
每行有第一个数字a,代表接下来的数字都 和 a 相连。

知识汇总:
割点:无向连通图中,如果删除某点后,图变成不连通了,则称该点为割点。
这里割点 和 桥 都是无向图里的概念,大家在这里不要混淆了。

求割点
一个顶点u是割点,当且仅当满足(1)或(2)
(1) u为树根,且u有多于一个子树。
(2) u不为树根,且满足存在(u,v)为树枝边(或称 父子边,即u为v在搜索树中的父亲),使得 dfn(u)<=low(v)。(也就是说 V 没办法绕过 u 点到达比 u dfn要小的点)
注:这里所说的树是指,DFS下的搜索树。

求割点 tarjan里 low 和 dfn
dfn[u]定义和前面类似,但是low[u]定义为u
或者u的子树中能够通过非父子边追溯到的
最早的节点的DFS开始时间
在Tarjan算法求割点我们要加一个数组 Father[u], 判断两者是否是父子边

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define maxn 10005
int dfn[maxn];///代表最先遍历到这个点的时间
int low[maxn];///这个点所能到达之前最早的时间点
int Father[maxn];///保存这个节点的父亲节点
int n, m, Time, top;///Time 时间点,  top用于栈操作
vector<vector<int> > G;

void Init()
{
G.clear();
G.resize(n+1);
memset(low, 0, sizeof(low));
memset(dfn, 0, sizeof(dfn));
memset(Father, 0, sizeof(Father));
Time = 0;
}

void Tarjan(int u,int fa)
{
low[u] = dfn[u] = ++Time;
Father[u] = fa;
int len = G[u].size(), v;

for(int i=0; i<len; i++)
{
v = G[u][i];

if(!dfn[v])
{
Tarjan(v, u);
low[u] = min(low[u], low[v]);
}
else if(fa != v)///假如我们在这里写上了 low[u] = min(low[v], low[u]),那么就相当于我们由v回了v之前的节点
low[u] = min(dfn[v], low[u]);
}
}
void solve()
{/**
求割点
一个顶点u是割点,当且仅当满足(1)或(2)
(1) u为树根,且u有多于一个子树。
(2) u不为树根,且满足存在(u,v)为树枝边(或称 父子边,即u为v在搜索树中的父亲),使得 dfn(u)<=low(v)。
(也就是说 V 没办法绕过 u 点到达比 u dfn要小的点)
注:这里所说的树是指,DFS下的搜索树*/
int RootSon = 0, ans = 0;///根节点儿子的数量
    bool Cut[maxn] = {false};///标记数组,判断这个点是否是割点

Tarjan(1,0);

for(int i=2; i<=n; i++)
{
int v = Father[i];
if(v == 1)///也是就说 i的父亲是根节点
RootSon ++;
else if(dfn[v] <= low[i])
Cut[v] = true;
}

for(int i=2; i<=n; i++)
{
if(Cut[i])
ans ++;
}
if(RootSon > 1)
ans++;

printf("%d\n", ans);
}
int main()
{
while(scanf("%d", &n), n)
{
int a, b;
char ch;
Init();
while(scanf("%d", &a), a)
{
while(scanf("%d%c",&b,&ch))
{
G[a].push_back(b);
G[b].push_back(a);
if(ch == '\n')
break;
}
}
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: