题意:
给定一组点集以及边集,并且保证组成的图一定是联通的。求点集,其中的点任意删去一个点以及其所连接的边,都会造成图的不连通。
输入数据比较麻烦:
每组例子,先输入一个n,代表点的个数;
然后输入一个数,该行都与这个数存在边,一直到一行的第一个数都为0时,这个图就结束了。
其实,要求的点集(这里是个数)就是求割点的个数
至于割点要怎么求,参照之前写的怎样求割点的算法:
http://blog.csdn.net/yumao19921006/article/details/8629814
代码:
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int a[105][105];
int vis[105];
int low[105];
int dfn[105];
bool ispoint[105];
//bool isver[100][100];
int n,m;
int times;
int DFS(int start,int deep,int father){
//if(deep==n)
// return 0;
low[start]=deep;
dfn[start]=deep;
int children=0;
for(int j=1;j<=n;j++){
if(a[start][j]==1&&j!=father){
if(vis[j]==1){
if(low[start]>dfn[j]){
low[start]=dfn[j];
}
}
else if(vis[j]==0){
children++;
vis[j]=1;
DFS(j,deep+1,start);
if((father==-1&&children>=2)||(dfn[start]<=low[j]&&father!=-1)){
if(!ispoint[start]){
times++;
//cout<<start<<" "<<father<<endl;
ispoint[start]=true;
}
//cout<<father<<" "<<children<<endl;
}
// if(dfn[start]<=low[j])
// isver[start][j]=true;
if(low[start]>low[j]){
low[start]=low[j];
}
}
}
}
vis[start]=2;
return 0;
}
int main(){
// int n,m;
while(cin>>n&&n){
memset(a,0,sizeof(a));
memset(ispoint,false,sizeof(ispoint));
// memset(isver,false,sizeof(isver));
memset(vis,0,sizeof(vis));
int tempn;
//getchar();
while(scanf("%d",&tempn),tempn){
int temp;
while(getchar()!='\n'){
scanf("%d",&temp);
//cin>>temp;
a[tempn][temp]=1;
a[temp][tempn]=1;
}
}
times=0;
vis[1]=1;
DFS(1,0,-1);
cout<<times<<endl;
}
return 0;
}