您的位置:首页 > 其它

ZOJ 1119 SPF

2015-08-03 16:36 375 查看
Tarjan算法求解割点

#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;

const int maxn=1111;//有多少个结点
vector<int>G[maxn];
int visited[maxn];//标记该节点有没有访问过
int node;//顶点数目
int tmpdfn;//dfs过程中记录当前的深度优先搜索序数
int dfn[maxn];//记录每个顶点的深度优先搜索序数
int low[maxn];//每个顶点的low值,根据该值来判断是否是关节点
int son;//根结点的有多少个孩子,如果大于等于2,则根结点为关节点
int subnets[maxn];//记录每个结点(去掉该结点后)的连通分量的个数

void init()
{
for(int i=0;i<maxn;i++) G[i].clear();
low[1]=dfn[1]=1;
tmpdfn=1;son=0;
memset(visited,0,sizeof(visited));
visited[1]=1;
memset(subnets,0,sizeof(subnets));
}

void dfs(int u)
{
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if(!visited[v])
{
visited[v]=1;
tmpdfn++; dfn[v]=low[v]=tmpdfn;
dfs(v);
low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u])
{
if(u!=1) subnets[u]++;
if(u==1) son++;
}
}
else low[u]=min(low[u],dfn[v]);
}
}

int main()
{
int u,v;
int number=1;
while(1)
{
node=0;
scanf("%d",&u);
if(u==0) break;
scanf("%d",&v);

if(u>node) node=u;
if(v>node) node=v;

//初始化
init();

//无向图
G[u].push_back(v);
G[v].push_back(u);

while(1)
{
scanf("%d",&u);
if(u==0) break;
scanf("%d",&v);

if(u>node) node=u;
if(v>node) node=v;

//无向图
G[u].push_back(v);
G[v].push_back(u);
}
if(number>1) printf("\n");
printf("Network #%d\n",number);
number++;
dfs(1);
if(son>1) subnets[1]=son-1;
int Find=0;
for(int i=1;i<=node;i++)
if(subnets[i])
{
Find=1;
printf("  SPF node %d leaves %d subnets\n",i,subnets[i]+1);
}
if(!Find) printf("  No SPF nodes\n");
}

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