POJ 1523 SPF 割点与桥的判断算法-Tarjan

题目链接:

POJ1523

题意:

问一个连通的网络中有多少个关节点,这些关节点分别能把网络分成几部分

题解:

Tarjan 算法模板题

顺序遍历整个图,可以得到一棵生成树:

树边:可理解为在DFS过程中访问未访问节点时所经过的边,也称为父子边

回边:可理解为在DFS过程中遇到已访问节点时所经过的边,也称为返祖边、后向边

对根节点u,若其有两棵或两棵以上的子树,则该根结点u为割点;

对非叶子节点u(非根节点),若其子树的节点均没有指向u的祖先节点的回边,说明删除u之后,根结点与u的子树的节点不再连通;则节点u为割点。

// 当(u,v)为树边且low[v]>dfn[u]时,表示v节点只能通过该边(u,v)与u连通,那么(u,v)即为割边。

用一个数组保存每个节点的子树个数即可

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#define maxn 1050
using namespace std;
int dfn[maxn],low[maxn];          //dfs序  和子树连接的最小节点
int vis[maxn];
vector<int>edge[maxn];
int child[maxn];
int num,son;
void init()
{
    memset(vis,0,sizeof(vis));
    memset(child,0,sizeof(child));
    vis[1]=1;
    num=0;
    son=0;
}
void Tarjan(int u)
{
    dfn[u]=low[u]=++num;
    vis[u]=1;
    for(int i=0; i<edge[u].size(); i++)
    {
        int v=edge[u][i];
        if(!vis[v])
        {
            Tarjan(v);
            low[u]=min(low[u],low[v]);
            if(dfn[u]<=low[v])       //得到子树
            {
                if(u!=1)
                    child[u]++;
                else
                    son++;
            }
        }
        else low[u]=min(low[u],dfn[v]);
    }
}
int main()
{
//    freopen("in.txt","r",stdin);
    int a,b;
    int Case=1;
    while(1)
    {
        while(scanf("%d",&a)&&a)
        {

            scanf("%d",&b);
            edge[a].push_back(b);
            edge[b].push_back(a);
        }
        init();

        Tarjan(1);
//        for(int i=1;i<=5;i++)
//        cout<<dfn[i]<<" "<<low[i]<<endl;
        if(Case>1)
            cout<<endl;
        printf("Network #%d\n",Case++);
        int flag=1;
        child[1]=son-1;
        for(int i=1; i<=1000; i++)
            if(child[i]>0)
            {
                flag=0;
                printf("  SPF node %d leaves %d subnets\n",i,child[i]+1);
            }
        if(flag)
            cout<<"  No SPF nodes"<<endl;

        for(int i=1; i<=1000; i++)
            edge[i].clear();
        scanf("%d",&a);
        if(a==0)
            break;
        scanf("%d",&b);
        edge[a].push_back(b);
        edge[b].push_back(a);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-29 01:20:37

POJ 1523 SPF 割点与桥的判断算法-Tarjan的相关文章

POJ - 1523 SPF(割点)

题目大意:给出一张图,问去割点后,连通分量的个数有多少 解题思路:割点的水题,套模版就可以 不得不吐槽一下输入.. #include <cstdio> #include <cstring> #define min(a,b) ((a)<(b)?(a):(b)) #define N 1010 #define M 2000010 struct Edge{ int to, next; }E[M]; int head[N], num[N], pre[N], lowlink[N]; in

POJ 1523 SPF 割点 Tarjan

SPF Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9317   Accepted: 4218 Description Consider the two networks shown below. Assuming that data moves around these networks only between directly connected nodes on a peer-to-peer basis, a

POJ 1523 SPF(强连通分量求割点)

题目地址:POJ 1523 这题猛的一看..貌似有点难的样子.不过仔细一想,那个每个割点所分成一次子图不就都能找到这个割点一次吗,那么只要记录下它作为割点的次数再+1不就行了.也算是求割点的裸题吧.这个题的输出很坑...需要注意一下.. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #incl

POJ 1523 SPF 解题报告

思路:使用tarjan算法求出割点,在枚举去掉每一个割点所能形成的联通块的个数. 注意:后来我看了下别的代码,发现我的枚举割点的方式是比较蠢的方式,我们完全可以在tarjan过程中把答案求出来,引入一下讨论: 如果这个割点是根节点,在tarjan算法中搜到几个孩子结点(low[v] >= dfn[u]),他就能割出几个联通块,如果这个割点是孩子结点,那么他所形成的联通块的个数+1,因为他还有一条与父亲结点间接或直接相连的边. 代码如下: #include<map> #include<

poj 1523 SPF 求割点以及删除该割点后联通块的数量

SPF Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7136   Accepted: 3255 Description Consider the two networks shown below. Assuming that data moves around these networks only between directly connected nodes on a peer-to-peer basis, a

POJ 1523 SPF 求割点的好(板子)题!

题意: 给个无向图,问有多少个割点,对于每个割点求删除这个点之后会产生多少新的点双联通分量 题还是很果的 怎么求割点请参考tarjan无向图 关于能产生几个新的双联通分量,对于每个节点u来说,我们判断他是否是割点,即判断是否满足他的儿子v的low[v]>dfn[u] 而这个时候割掉这个点就会让双联通分量增加,所以搞一个数组记录一下这个操作的次数就行 请注意在是否是根节点的问题上特判 !!注意输出格式!! 1 #include<cstdio> 2 #include<algorithm

POJ 1523 SPF(割点)

大致题意: 给出一个连通的无向图,求哪些点是割点,对于每个割点,求出去掉这个点后连通分量的个数.如果没有割点的话输出" No SPF nodes". 思路: 求割点用tarjan即可,然后要求删除割点后连通分量的个数,每次找到割点,再在从割点dfs即可,也可以直接在tarjan算法中记录child个数.那么如果割点是根,那么答案就是child,不是根的割点答案是child+1 //188K 0MS C++ 2121B #include<cstdio> #include<

poj 1523 SPF 无向图求割点

SPF Description Consider the two networks shown below. Assuming that data moves around these networks only between directly connected nodes on a peer-to-peer basis, a failure of a single node, 3, in the network on the left would prevent some of the s

poj 1523 SPF

SPF http://poj.org/problem?id=1523 Time Limit: 1000MS   Memory Limit: 10000K       Description Consider the two networks shown below. Assuming that data moves around these networks only between directly connected nodes on a peer-to-peer basis, a fail