poj1523(割点)

注意求解割点的内容:以下内容是在自己学习中总结出来的:
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=1005;
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,int fa){
	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,u);
			low[u]=min(low[u],low[v]);
			if(u!=root&&low[v]>=dfn[u]){
				flag[u]++;
			}
			if(u==root&&child>1){
				flag[u]++;
			}
		}else if(i!=fa){
			low[u]=min(low[u],dfn[v]);
		}
	}
}
int main(){
	int count=1;
	int a,b;
	while(scanf("%d",&a)){
		if(a==0)break;
		n=a;
		memset(low,0,sizeof(low));
		memset(dfn,0,sizeof(dfn));
		for(int i=0;i<=maxx;i++){
			flag[i]=1;
		}
		for(int i=0;i<=maxx;i++){
			G[i].clear();
		}
		root=1,index=1;
		scanf("%d",&b);
		n=max(n,b);
		G[a].push_back(b);
		G[b].push_back(a);
	    while(scanf("%d",&a)){
	    	if(a==0)break;
	    	scanf("%d",&b);
	    	n=max(n,b);
	    	n=max(n,a);
	    	G[a].push_back(b);
	    	G[b].push_back(a);
		}
		int ans=0;
		dfs(1,root);
		int vis=0;
		cout<<"Network #"<<count++<<endl;
		for(int i=1;i<=n;i++){
			if(flag[i]>1){
				vis=1;
				cout<<"  SPF node "<<i<<" leaves "<<flag[i]<<" subnets"<<endl;
			}
		}
		if(vis==0){
			cout<<"  No SPF nodes"<<endl;
		}
		cout<<endl;
	}
	return 0;
} 
相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页