zoukankan      html  css  js  c++  java
  • poj 1523求割点

    题意:给出一个无向图,求割点以及去除这个点后图分为几部分;

    思路:割点定义:去掉该点后图将分成几个部分。割点:(1)当k为根节点且有>1个分支,则去除该点后图便被分成几个分支。(2)DFN[v]<Low[j]表示v的子节点不会有回路回到v的祖先。

    代码:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    #define MAXN 1005
    #define MAXM 1005*1005
    struct Edge
    {
        int to,next;
    }edge[MAXM];
    int Low[MAXN],DFN[MAXN],first[MAXN],son,vis[MAXN];
    int n,count,cut[MAXN],tot,root;
    void addedge(int v,int w)
    {
        edge[tot].to=w;
        edge[tot].next=first[v];
        first[v]=tot++;
    }
    void Tarjan(int v)
    {
        DFN[v]=Low[v]=++count;
        for(int i=first[v];i!=-1;i=edge[i].next)
        {
            int j=edge[i].to;
            if(!DFN[j])
            {
                    Tarjan(j);
                    if(root==v)
                    {
                        son++;
                        if(son>1)
                            cut[v]=1;
                    }
                    else
                    {
                        Low[v]=min(Low[j],Low[v]);
                        if(DFN[v]<=Low[j])cut[v]=1;
                    }
            }
            else
            {
                Low[v]=min(Low[v],DFN[j]);
            }
        }
    }
    void dfs(int u)
    {
        vis[u]=1;
        for(int i=first[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].to;
            if(!vis[v])
            {
                dfs(v);
            }
        }
    }
    int main()
    {
        int x,y,t=0;
        while(scanf("%d",&x),x)
        {
            t++;
            memset(DFN,0,sizeof(DFN));
            memset(first,-1,sizeof(first));
            memset(Low,0,sizeof(Low));
            memset(cut,0,sizeof(cut));
            n=0;
            scanf("%d",&y);
            addedge(x,y);
            addedge(y,x);
            n=max(x,y);
            count=0;
            while(scanf("%d",&x),x)
            {
                scanf("%d",&y);
                addedge(x,y);
                addedge(y,x);
                n=max(x,y);
            }
    
    
                    son=0;
                    root=1;
                    Tarjan(1);
            printf("Network #%d
    ",t);//cout<<1111<<endl;
            int ans=0;
            int flag=0;
            for(int i=1;i<=n;i++)
            {
                if(cut[i]==1)
                {
                    flag=1;
                    memset(vis,0,sizeof(vis));
                    vis[i]=1;
                    int son1=0;
                    for(int j=first[i];j!=-1;j=edge[j].next)
                    {
                        int k=edge[j].to;
                        if(!vis[k])
                        {
                            dfs(k);
                            son1++;
                        }
                    }
                    printf("  SPF node %d leaves %d subnets
    ",i,son1);
                }
            }
    
            if(!flag)
                printf("  No SPF nodes
    ");
            printf("
    ");
        }
        return 0;
    }
    


     

  • 相关阅读:
    Java
    Java
    Java
    Java
    运算问题
    Idea常用快捷键
    java变量和变量命名规范
    java常用数据类型和基本数据类型转换和进制和大数运算
    java注释和标识符规范
    使用命令行生成的第一个java程序
  • 原文地址:https://www.cnblogs.com/amourjun/p/5134124.html
Copyright © 2011-2022 走看看