求去点割点后,能把图分成几个块。
若u为割点,记cnt[u]为u的子节点数,则去掉u后,图被分成cnt[u]+1个部分(每个子节点的部分和u的祖先的部分),若u为dfs树的根,则分成cnt[u]个部分(根节点没有祖先)
#include<iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<queue>
#include<stack>
#include<vector>
using namespace std;
const int inf=0x7ffffff;
const double PI=acos(-1.0);
const double eps=1e-8;
bool map[1010][1010];
int low[1010];
int dfn[1010];
bool vis[1010];
int cnt[1010];
int depth,n,son;
void init()
{
memset(map,0,sizeof(map));
memset(vis,0,sizeof(vis));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(cnt,0,sizeof(cnt));
}
void dfs(int v)
{
dfn[v]=depth;
low[v]=depth++;
vis[v]=true;
for(int i=1;i<=n;i++)
if(map[v][i])
{
if(!vis[i])
{
dfs(i);
low[v]=min(low[i],low[v]);
if(low[i]>=dfn[v] && v!=1)
cnt[v]++;
else if(v==1) son++;
}
else low[v]=min(low[v],dfn[i]);
}
}
int main()
{
int a,b,cas=1,c,d;
while(~scanf("%d",&a),a)
{
scanf("%d",&b);
n=max(a,b);
init();
map[a][b]=map[b][a]=1;
while(1)
{
scanf("%d",&c);
if(c==0) break;
scanf("%d",&d);
map[c][d]=map[d][c]=1;
n=max(n,c);
n=max(n,d);
}
son=0;
depth=1;
dfs(1);
bool flag=false;
if(son>1)
cnt[1]=son-1;
printf("Network #%d\n",cas++);
for(int i=1;i<=n;i++)
if(cnt[i])
{
flag=1;
printf(" SPF node %d leaves %d subnets\n",i,cnt[i]+1);
}
if(!flag) puts(" No SPF nodes");
puts("");
}
}
225

被折叠的 条评论
为什么被折叠?



