您的位置:首页 > 其它

[POJ1144]Network(tarjan求割点)

2016-11-07 15:55 351 查看

题目描述

传送门

题意:求一个无向图中割点的数量。

题解

tarjan求割点模板题。

dfn表示点x的时间戳,low表示点x通过其后代最早能到达的点,is_cut表示点x的后代最多能有多少个连通块。

假设一个点是割点,如果这个点是第一个被访问点,那么如果它后代能形成一个以上的连通块的话它就是割点。如果这个点不是第一个被访问的点,那么如果它后代能形成一个或以上的连通块的话它就是割点。

代码

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define N 20005

int n,m,p,dfs_clock,ans;
int tot,point
,nxt[N*2],v[N*2];
int dfn
,low
,is_cut
;
bool flag;

void clear()
{
dfs_clock=ans=0;
tot=0;memset(v,0,sizeof(v));memset(point,0,sizeof(point));memset(nxt,0,sizeof(nxt));
memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));memset(is_cut,0,sizeof(is_cut));
}
int read()
{
int x=0; char ch=getchar();
while (ch<'0'||ch>'9')
{
ch=getchar();
if (ch=='\n') flag=true;
}
while (ch>='0'&&ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
if (ch=='\n') flag=true;
}
return x;
}
void add(int x,int y)
{
++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y;
++tot; nxt[tot]=point[y]; point[y]=tot; v[tot]=x;
}
void tarjan(int x)
{
dfn[x]=low[x]=++dfs_clock;
for (int i=point[x];i;i=nxt[i])
if (!dfn[v[i]])
{
tarjan(v[i]);
low[x]=min(low[x],low[v[i]]);
if (dfn[x]<=low[v[i]]) is_cut[x]++;
}
else low[x]=min(low[x],dfn[v[i]]);
}
int main()
{
while (1)
{
n=read();
if (!n) break;
clear();
while (1)
{
m=read();
if (!m) break;flag=false;
while (!flag)
{
p=read();
add(m,p);
}
}
for (int i=1;i<=n;++i)
if (!dfn[i]) tarjan(i);
for (int i=1;i<=n;++i)
if ((i==1&&is_cut[i]>1)||(i!=1&&is_cut[i])) ans++;
printf("%d\n",ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: