• 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;
    }
    


     

  • 相关阅读:
    深入理解redis数据类型
    js获取带#号链接后的参数
    js对象深拷贝与浅拷贝
    VUE + ElementUI 从搭建到运行
    python 输入一个整数,判断其是否既是3的倍数,又是5的倍数
    输入一个三位整数,顺序打印个位、十位、百位上的数
    python 输入三个整数,按照从小到大的顺序打印
    python 运算符与分支结构
    python 变量定义
    python 环境安装
  • 原文地址:https://www.cnblogs.com/amourjun/p/5134124.html
Copyright © 2020-2023  润新知