900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > poj1144(割点)

poj1144(割点)

时间:2021-01-13 02:42:28

相关推荐

poj1144(割点)

题意:给出N,表示网络数;在每个街区的第一行中,有N<100的位置数,再给出一个最多N行的每一行都包含一个地方的数目,然后是从这个地方直接到的一些地方的数目。代表第一个数和后面的其他数都是连接的。

求割点的数目:

注意求解割点的内容:以下内容是在自己学习中总结出来的:

1.割点:在无向图中,若删去该点后图不连通,则此点为割点。

2.low[u]定义:表示在DFS回溯的前提下,该节点vi不通过父节点到vi这条边所能连通的顶点时间戳最小值。初始时,low[i]=dfn[i]当dfs处理到末尾的向前回溯,同时维护:low[fa]=min{low[fa],low[child]}

3.dfn[i]:表示在DFS回溯的前提下,该节点vi被遍历的时间先后顺序,顺序递增。

4.顶点u的割点的条件:

(1).特判树根:u为树根,且u有多于一个子树

(2).u不为树根:在递归树上u有子节点v,满足:dfn[u] <=low[v]

#include<iostream>#include<algorithm>#include<cstring>#include<vector>#include<cmath>#include<cstdio>using namespace std;const int maxx=105;const int inf=0x3f3f3f3f;int dfn[maxx];int low[maxx];int n,m;int root,index;int flag[maxx];vector<int>G[maxx];void dfs(int u){index++;int child=0;dfn[u]=low[u]=index;for(int i=0;i<G[u].size();i++){int v=G[u][i];if(dfn[v]==0){child++;dfs(v);low[u]=min(low[u],low[v]);if(u!=root&&low[v]>=dfn[u]){flag[u]=1;}elseif(u==root&&child>1){flag[u]=1;}}else {low[u]=min(low[u],dfn[v]);}}}int main(){while(scanf("%d",&n)!=EOF){if(n==0)break;memset(low,0,sizeof(low));memset(dfn,0,sizeof(dfn));memset(flag,0,sizeof(flag));for(int i=0;i<=n;i++){G[i].clear();}root=1,index=1;int t,tt;while(scanf("%d",&t)==1){if(t==0)break;while(getchar()!='\n'){scanf("%d",&tt);G[t].push_back(tt); G[tt].push_back(t); }}int ans=0;dfs(1);for(int i=1;i<=n;i++){if(flag[i]==1){ans++;}}cout<<ans<<endl;}return 0;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。