POJ1523:割点

POJ1523

题意:问一个连通的网络中有多少个关节点,这些关节点分别能把网络分成几部分

题解:求割点的题目。给的网络一定是连通的,割点就是在无向连通图的前提下。最后注意输出,每两个Case之间有个blank。

代码:

#include <cstring>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <stack>
#include <vector>
using namespace std;
int const N = 1000 + 10;
vector<int>G[N];
int cnt,scc,T,root;
int pre[N],lowlink[N],sccno[N],son[N];
int n;
stack<int>st;
bool Init(){
	int u,v;
	n = 0;
	for(int i=0;i<N;i++)	G[i].clear();
	while(~scanf("%d",&u) && u){
		scanf("%d",&v);
		n = max(n,max(u,v));
		G[u].push_back(v);
		G[v].push_back(u);
		while(~scanf("%d",&u) && u){
			scanf("%d",&v);
			G[u].push_back(v);
			G[v].push_back(u);
			n = max(n,max(u,v));
		}
		return true;
	}
	return false;
}
void dfs(int u){
	pre[u] = lowlink[u] = ++cnt;
	st.push(u);
	for(int i=0;i<G[u].size();i++){
		int v = G[u][i];
		if(!pre[v]){
			dfs(v);
			lowlink[u] = min(lowlink[v],lowlink[u]);
			if(lowlink[v] >= pre[u]){
				if(u != root)	son[u]++;
				else	son[root]++; 
			}
		}else if(!sccno[v]){
			lowlink[u] = min(lowlink[u],pre[v]);
		}
	}
	if(pre[u] == lowlink[u]){
		scc++;
		while(1){
			int x = st.top();	st.pop();
			sccno[x]= scc;
			if(x == u)	break;
		}
	}
}
void Tarjain(){
	cnt = scc = 0;
	while(!st.empty())	st.pop();
	root = 1;
	memset(pre,0,sizeof(pre));
	memset(sccno,0,sizeof(sccno));
	memset(son,0,sizeof(son));
	dfs(1);
}
void solve(){
	if(T)	cout<<endl;
	printf("Network #%d\n",++T);
	int ans = 0;
	if(son[root] > 1)	ans++;
	for(int i=2;i<=n;i++)
		if(son[i])	ans++;
	if(!ans)	printf("  No SPF nodes\n");
	else{
		for(int i=1;i<=n;i++){
			if(i == root && son[root] > 1)
				printf("  SPF node %d leaves %d subnets\n",i,son[i]);  
			else if(i != root && son[i])
				printf("  SPF node %d leaves %d subnets\n",i,son[i]+1);   //+1,因为还和它的父亲结点连接
		}
	}
}
int main(){	
	T = 0;
	while(Init()){
		Tarjain();	
		solve();
	}
}


 

猜你喜欢

转载自blog.csdn.net/weixin_42264485/article/details/88546601