http://poj.org/problem?id=1523
题目描述:
给定一张无向图,求割点,并求删除该割点所得的连通分支数
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define pb push_back
typedef long long ll;
const int MAXN=1010;
using namespace std;
vector<int> g[MAXN];
int pre[MAXN],low[MAXN];
int subnets[MAXN];
bool iscut[MAXN];
int dfs_clock;
int node;
void init(){
for(int i=0;i<MAXN;++i) g[i].clear();
memset(subnets,0,sizeof(subnets));
memset(low,0,sizeof(low));
memset(iscut,0,sizeof(iscut));
memset(pre,0,sizeof(pre));
dfs_clock=0;
node=0;
}
int dfs(int u,int fa){
int lowu=pre[u]=++dfs_clock;
int child=0;
for(int i=0;i<g[u].size();++i){
int v=g[u][i];
if(!pre[v]){
child++;
int lowv=dfs(v,u);
lowu=min(lowu,lowv);
if(lowv>=pre[u]){
iscut[u]=true;
subnets[u]++;
}
}
else if(pre[v]<pre[u]&&v!=fa){
lowu=min(lowu,pre[v]);
}
}
if(fa<0&&child==1) iscut[u]=0;
low[u]=lowu;
return lowu;
}
void solve(){
bool flag=false;
if(iscut[1]) subnets[1]--;
for(int i=1;i<=node;++i){
if(iscut[i]){
flag=true;
printf( " SPF node %d leaves %d subnets\n",i,subnets[i]+1);
}
}
if(!flag) printf( " No SPF nodes\n" );
printf("\n");
}
int main()
{
int u,v,cas=1;
while(scanf("%d",&u)&&u){
init();
scanf("%d",&v);
g[u].push_back(v);
g[v].push_back(u);
node=max(node,max(u,v));
while(scanf("%d",&u)&&u){
scanf("%d",&v);
g[u].push_back(v);
g[v].push_back(u);
node=max(node,max(u,v));
}
printf("Network #%d\n",cas++);
dfs(1,-1);
solve();
}
return 0;
}