POJ1144——网络(求割点)
描述
电话线公司(TLC)正在建立一个新的电话有线网络。它们连接多个由1到N的整数编号的地方。没有两个地方有相同的数字。线路是双向的,并且总是连接在一起的两个地方,并且在每个地方线路结束在电话交换机中。每个地方都有一个电话交换机。从每一个地方都 可以通过线路到达其他地方,但是它不需要直接连接,它可以通过几个交换机。电源不时在某个地方发生故障,然后交换机不工作。TLC的官员认识到,在这种情况下,除了失败的地方是不可达到的事实外,还可能导致其他一些地方无法相互连接。 在这种情况下,我们会说这个地方( 发生故障的地方)至关重要。现在官员正在试图编写一个方案来查找所有关键地点的数量。帮助他们
输入
输入文件由若干组数据组成。每组数据块描述一个网络。在每组数据的的第一行中,存在N < 100的位数。
下一个最多N行中的每一行包含一个地方的数字,之后是与该地方有直接线的某些地方的数字。这些最多N行完全描述网络,即网络中两个地方的每个直接连接至少包含一行。一行中的所有数字都
被一个空格分开。每组数据以仅包含0的行结束。最后一组数据只有一行N = 0;
【提醒】行末判断用'\r'不用'\n’。因为数据是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()!='\r'){
scanf("%d",&v);
addedge(u,v);
}
}
tarjan(1);
for(int i=1;i<=n;i++){
if(cut[i])ans++;
}
cout<<ans<<'\n';
}
}