• 【POJ 1523】SPF(割点)


     儿子数大于1的树根或者 Low[v] >= DFN[u]的非树根节点v 就是割点。

    #include <cstdio>
    #include <cstring>
    
    const int N = 1001;
    const int M = 1000010;
    struct Edge
    {
        int to,next;
        bool cut;//是否为桥的标记
    }edge[M];
    int head[N],tot;
    int Low[N],DFN[N],Stack[N];
    int Index,top;
    bool Instack[N];
    bool cut[N];//是否为割点
    int add_block[N];//删除一个点后增加的连通块
    int bridge;
    int va[N];
    void addedge(int u,int v)
    {
        edge[tot].to = v;edge[tot].next =head[u];edge[tot].cut = false;
        head[u] = tot++;
    }
    void Tarjan(int u,int pre)
    {
        int v;
        Low[u] = DFN[u] = ++Index;
        Stack[top++] = u;
        Instack[u] = true;
        int son = 0;
        for(int i = head[u];~i;i = edge[i].next)
        {
            v = edge[i].to;
            if(v == pre)continue;
            if( !DFN[v] )
            {
                son++;
                Tarjan(v,u);
                if(Low[u] > Low[v])Low[u] = Low[v];
                //
                if(Low[v] > DFN[u])
                {
                    bridge++;
                    edge[i].cut = true;
                    edge[i^1].cut = true;
                }
                if(u != pre && Low[v] >= DFN[u])//不是树根
                {
                    cut[u] = true;
                    add_block[u]++;
                }
            }
            else if( Low[u] > DFN[v])
                Low[u] = DFN[v];
        }
        //树根,分支数大于1
        if(u == pre && son > 1)cut[u] = true;
        if(u == pre)add_block[u] = son - 1;
        Instack[u] = false;
        top--;
    }
    void solve(){
        memset(DFN,0,sizeof DFN);
        memset(Instack,0,sizeof Instack);
        memset(add_block,0,sizeof add_block);
        memset(cut,false,sizeof cut);
        Index=top=0;
        int cnt=0,ans=0;
        for(int i=1;i<N;i++)
            if(va[i]&&!DFN[i]){
                Tarjan(i, i);
                cnt++;
            }
        for(int i=1;i<N;i++)
            if(cut[i]){
                ans++;
                printf("  SPF node %d leaves %d subnets
    ",i,cnt+add_block[i]);
            }
        if(ans==0)
            puts("  No SPF nodes");
        
    }
    void init(){
        memset(head,-1,sizeof head);
        memset(va,0,sizeof va);
        tot=0;
    }
    int main(){
        int u,v,cas=0;
        init();
        while(~scanf("%d",&u)){
            if(u==0&&tot){
                printf("Network #%d
    ",++cas);
                solve();
                init();
                puts("");
                continue;
            }
            scanf("%d",&v);
            addedge(u,v);
            addedge(v,u);
            va[u]=va[v]=1;
        }
    }

      

  • 相关阅读:
    tab切换与表格展示
    ajax
    api
    slice() 方法
    iframe跳转
    快排序
    【问题排查】cpu占用过高排查
    LOJ6013 负载平衡 [最小费用最大流]
    随机序列 [思维题, 组合数]
    P1777 帮助 [状压dp]
  • 原文地址:https://www.cnblogs.com/flipped/p/5759362.html
Copyright © 2020-2023  润新知