`
Coco_young
  • 浏览: 120064 次
  • 性别: Icon_minigender_1
  • 来自: 湖南长沙
社区版块
存档分类
最新评论

[割点问题]poj_1523_SPF

 
阅读更多

题目大意:给定一个网络,看是否有关节点存在(即割点,即去除该点后,图变成非连通图),如果存在输出该节点和去除该节点后连通子图的个数,如果不存在割点即输出没有割点存在。


求割点直接用dfs解决即可,问题在于统计去除该割点后,连通子图的个数,其实在dfs时,遇到割点时,只要发现其儿子结点的low值比该割点的dfn值大或相等,那么去除该结点后,其儿子结点能到达的所有结点 必定构成一个连通子图,这样用一个son数组记录所有这样的儿子结点的个数,最后加上割点的父亲结点能到达的所有结点形成的连通子图,即为去除该结点后整个图的连通子图的个数。


代码如下:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
using namespace std;
const int MAXN = 1100;
int ROOT = 1;
#define MIN(a,b) a>b?b:a
#define MAX(a,b) a>b?a:b
int vis[MAXN],cut[MAXN],low[MAXN],dfn[MAXN],son[MAXN],p[MAXN],used[MAXN];
vector<int> g[MAXN];
void init()
{
	memset(vis,0,sizeof(vis));
	memset(cut,0,sizeof(cut));
	memset(son,0,sizeof(son));
	memset(used,0,sizeof(used));
	for(int i=0;i<MAXN;i++)g[i].clear(),p[i]=i;
}
int find(int x)
{
	return x==p[x]?x:p[x]=find(p[x]);
}
void merge(int x,int y)
{
	int r1 = find(x),r2 = find(y);
	if(r1==r2)return;
	p[r1]=r2;
}
int conn()
{
	int cnt =0;
	for(int i=0;i<MAXN;i++)
	{
		if(p[i]==i&&used[i])cnt++;
	}
	return cnt;
}
void dfs(int u,int father,int deep)
{
	vis[u] = 1;
	dfn[u] = low[u] = deep;
	int s = 0,record = 0;
	for(int i=0;i<g[u].size();i++)
	{
		int v = g[u][i];
		if(!vis[v])
		{
			dfs(v,u,deep+1);
			s++;
			low[u] = MIN(low[u],low[v]);
			if((u==ROOT&&s>=2)||(u!=ROOT&&low[v]>=dfn[u]))
			{
				cut[u] = 1;record++;
			}
		}
		else if(v!=father)
		{
			low[u] = MIN(low[u],dfn[v]);
		}
	}
	son[u] = record;
}
int main()
{
	int u,v;init();int cas=0,start=1;
	while(scanf("%d",&u))
	{
		if(u!=0)
		{
            start = 0;
			scanf("%d",&v);
			g[u].push_back(v);
			g[v].push_back(u);
			used[u] = used[v] = 1;
			merge(u,v);
			continue;
		}
		if(u==0&&start)break;
        for(int i=0;i<MAXN;i++)
        {
            if(!vis[i]&&used[i])
            {
                ROOT = i;
                dfs(ROOT,-1,0);
            }
        }
		bool flag = false;int cnt = conn();
		printf("Network #%d\n",++cas);
		for(int i=0;i<MAXN;i++)
		{
            if(cut[i])
            {
                flag = true;
                printf("  SPF node %d leaves %d subnets\n",i,son[i]+cnt);
            }
        }
		if(!flag)
		{
			printf("  No SPF nodes\n");
		}
		printf("\n");
		init();start = 1;
	}
	return 0;
}


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics