您的位置:首页 > 其它

poj1523 求割点 及 该割点 可以 把该图分成几个连通分量

2013-05-21 12:33 375 查看
思路:当一个几点为割点时必须满足两个基本条件:
情况1: u为根且至少为两颗子树.
情况2:u不为根且存在一个u在深搜树中的子女满足low[v]>=dfn[u],u为父亲v为子女
#include<iostream>
#include<algorithm>
#include<string.h>
#include<list>
#include<cstdio>
using namespace std;
const int Max=1001;
int t,v1,v2;
list<int>Gra[Max];
int flag,root,sum;
int spf[Max];
int low[Max],lab[Max];
int vis[Max];
int MIN(int a,int b)
{
return a>b?b:a;
}
void dfs(int pox,int fa)
{
low[pox]=lab[pox]=sum++;
list<int>::iterator it;
int counter=0;
for(it=Gra[pox].begin(); it!=Gra[pox].end(); it++)
{
int v=*it;
if(!lab[v])
{
counter++;
dfs(v,pox);
low[pox]=MIN(low[pox],low[v]);
if(pox==root&&counter>=2||(pox!=root&&low[v]>=lab[pox]))
spf[pox]=flag=true;
}
else if(v!=fa)
low[pox]=MIN(low[pox],lab[v]);
}
}
void find(int u)
{
vis[u]=1;
list<int>::iterator it;
for(it = Gra[u].begin(); it != Gra[u].end(); it++)
if(!vis[*it])
find(*it);
}
int main()
{
for(t=1;; t++)
{
scanf("%d",&v1);
if(v1==0)
break;
for(int i=0; i<Max; i++)
Gra[i].clear();
memset(spf,0,sizeof(spf));
memset(low,0,sizeof(low));
memset(lab,0,sizeof(lab));
while(v1!=0)
{
scanf("%d",&v2);
Gra[v1].push_back(v2);
Gra[v2].push_back(v1);
root=v1;
scanf("%d",&v1);
}
sum=1;
flag=false;
dfs(root,-1);
printf("Network #%d\n", t);
if(flag)
{
for(int i=1; i<Max; i++)
{
if(spf[i]==0)
continue;
int cnt=0;
memset(vis,0,sizeof(vis));
vis[i]=true;
list<int>::iterator it;
for(it=Gra[i].begin(); it!=Gra[i].end(); it++)
{
if(!vis[*it])
{
cnt++;
find(*it);
}
}
printf("  SPF node %d leaves %d subnets\n", i, cnt);
}
}
else
printf("  No SPF nodes\n");
printf("\n");
}
return 0;
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐