POJ1144——网络(求割点)

描述

电话线公司(TLC)正在建立一个新的电话有线网络。它们连接多个由1到N的整数编号的地方。没有两个地方有相同的数字。线路是双向的,并且总是连接在一起的两个地方,并且在每个地方线路结束在电话交换机中。每个地方都有一个电话交换机。从每一个地方都 可以通过线路到达其他地方,但是它不需要直接连接,它可以通过几个交换机。电源不时在某个地方发生故障,然后交换机不工作。TLC的官员认识到,在这种情况下,除了失败的地方是不可达到的事实外,还可能导致其他一些地方无法相互连接。 在这种情况下,我们会说这个地方( 发生故障的地方)至关重要。现在官员正在试图编写一个方案来查找所有关键地点的数量。帮助他们

输入

输入文件由若干组数据组成。每组数据块描述一个网络。在每组数据的的第一行中,存在N < 100的位数。

下一个最多N行中的每一行包含一个地方的数字,之后是与该地方有直接线的某些地方的数字。这些最多N行完全描述网络,即网络中两个地方的每个直接连接至少包含一行。一行中的所有数字都

被一个空格分开。每组数据以仅包含0的行结束。最后一组数据只有一行N = 0;

【提醒】行末判断用' '不用' ’。因为数据是windows下生成,在linux下测评。

输出

输出包含每个块除了输入文件中的最后一行,包含关键位置数。

样例输入 

5
5 1 2 3 4
0
6
2 1 3
5 4 6 2
0
0

样例输出 

1
2

不说了吧

求割点的板子题

tarjan找割点就是了

只是恕我直言这读入太恶心了

#include<bits/stdc++.h>
using namespace std;
inline int read(){
	char ch=getchar();
	int res=0;
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
	return res;
}
int n,m,adj[105],nxt[10005],to[10005],dfn[105],low[105],cut[105],ans,cnt,tot;
inline void addedge(int u,int v){
	nxt[++cnt]=adj[u],adj[u]=cnt,to[cnt]=v;
	nxt[++cnt]=adj[v],adj[v]=cnt,to[cnt]=u;
}
stack<int> stk;
inline void tarjan(int u){
	dfn[u]=low[u]=++tot;
	int flag=0;
	for(int e=adj[u];e;e=nxt[e]){
		int v=to[e];
		if(!dfn[v]){
			tarjan(v);
			low[u]=min(low[u],low[v]);
			if(dfn[u]<=low[v]){
				if(++flag>1||u!=1)cut[u]=1;//what is the use of "u!=1"
			}
		}
		else low[u]=min(low[u],dfn[v]);
	}
}
int main(){
    while(scanf("%d",&n)&&n)
    {
		cnt=0,ans=0,tot=0;
		int u,v;
		memset(cut,0,sizeof(cut));
		memset(adj,0,sizeof(adj));
		memset(dfn,0,sizeof(dfn));
		memset(low,0,sizeof(low));
		memset(nxt,0,sizeof(nxt));
		memset(to,0,sizeof(to));
		while(scanf("%d",&u)&&u){
			while(getchar()!='
'){
				scanf("%d",&v);
				addedge(u,v);
			}
		}
		tarjan(1);
		for(int i=1;i<=n;i++){
			if(cut[i])ans++;
		}
		cout<<ans<<'
';
	}
}
原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366434.html