• 无向图的割点和桥


    割点:

    void tarjan(int u){
        dfn[u]=low[u]=++cnt;
        int flag=0;
        for(int i=head[u];~i;i=e[i].nextt){
            int v=e[i].v;
            if(!dfn[v]){
                tarjan(v);
                low[u]=min(low[u],low[v]);
                if(low[v]>=dfn[u]){//就一个割点判断法则没必要解释什么了吧?
                    flag++;
                    if(u!=rt||flag>1)cut[u]=1;
                }
            }else low[u]=min(low[u],dfn[v]);
        }
    }
    View Code

    桥:

    void tarjan(int u,int in_edge){//in_edge表示递归进入每个节点的边的编号 
        dfn[u]=low[u]=++cnt;
        for(int i=head[u];~i;i=e[i].nextt){
            int v=e[i].v;
            if(!dfn[v]){
                tarjan(v,i);
                low[u]=min(low[u],low[v]);//在搜索树上的边
                if(low[y]>dfn[u])//桥判定法则
                    bridge[i]=bridge[i^1]=1;//这条边和它的反向边都是桥
            }else if(i!=(in_edge^1))///实际上也就是不要走到父亲去 
                low[u]=min(low[u],dfn[v]);//不在搜索树上的边
        }
    }
    int main(){
        n=read();m=read();
        for(int i=1;i<=m;i++){
            int x=read(),y=read();
            addedge(x,y);addedge(y,x);
        }
        for(int i=1;i<=n;i++)
            if(!dfn[i])tarjan(i,0);
        for(int i=0;i<tot;i+=2)
            if(bridge[i])
                printf("%d %d
    ",e[i^1].v,e[i].v);//输出桥两边的点
                //printf("%d %d
    ",to(i^1),to(i));//输出桥两边的点
    }
    View Code

    poj 1144

    http://poj.org/problem?id=1144

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    using namespace std;
    typedef long long ll;
    int mi(int x,int y){
        return x<y?x:y;
    }
    inline int read(){
        int sum=0,x=1;
        char ch=getchar();
        while(ch<'0'||ch>'9'){
            if(ch=='-')
                x=0;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9'){
            sum=(sum<<1)+(sum<<3)+(ch^48),ch=getchar();
        }
        //cout<<"~~"<<endl;
        return x?sum:-sum;
    }
    inline void write(int x){
        if(x<0)
            putchar('-'),x=-x;
        if(x>9)
            write(x/10);
        putchar(x%10+'0');
    }
    const int M=101;
    int dfn[M],low[M],head[M],cut[M],tot,cnt,son;
    struct node{
        int v,nextt;
    }e[M*M];
    void addedge(int u,int v){
        e[tot].v=v;
        e[tot].nextt=head[u];
        head[u]=tot++;
    }
    
    void tarjan(int u){
        dfn[u]=low[u]=++cnt;
        for(int i=head[u];~i;i=e[i].nextt){
            int v=e[i].v;
            if(!dfn[v]){
                tarjan(v);
                if(u==1)
                    son++;
                else{
                    low[u]=mi(low[u],low[v]);
                    if(dfn[u]<=low[v])
                        cut[u]=1;
                }
            }
            else
                low[u]=mi(low[u],dfn[v]);
        }
    }
    
    int n;
    void init(){
        for(int i=0;i<=n;i++)
            dfn[i]=low[i]=cut[i]=0,head[i]=-1;
        son=0,tot=0,cnt=0;
    }
    int main(){
        while(~scanf("%d",&n)&&n){
            init();
            int u;
            while(scanf("%d",&u)&&u){
                while(getchar()!='
    '){
                    int v;
                    scanf("%d",&v);
                    addedge(u,v);
                    addedge(v,u);
                }
            }
            tarjan(1);
            int ans;
            if(son>=2)
                ans=1;
            else
                ans=0;
            for(int i=1;i<=n;i++)
                if(cut[i])
                    ans++;
            //cout<<ans<<endl;
            write(ans);
            putchar('
    ');
        }
        return 0;
    }
    View Code

    题:http://poj.org/problem?id=1523

    题意:问割点包含的点的个数

    #include<bits/stdc++.h>
    using namespace std;
    const int M=1e3+3;
    int head[M],dfn[M],cut[M],low[M],n,tot,cnt,rt;
    struct node{
        int v,nextt;
    }e[M*10];
    void addedge(int u,int v){
        e[tot].v=v;
        e[tot].nextt=head[u];
        head[u]=tot++;
    }
    void tarjan(int u){//cout<<"!!"<<endl;
        dfn[u]=low[u]=++cnt;
        int flag=0;
        for(int i=head[u];~i;i=e[i].nextt){
            int v=e[i].v;
            if(!dfn[v]){
                tarjan(v);
                low[u]=min(low[u],low[v]);
                if(low[v]>=dfn[u]){
                    flag++;
                    if(u!=rt||flag>1)
                        cut[u]++;
                }
            }
            else
                low[u]=min(low[u],dfn[v]);
        }
    }
    void init(){
        memset(head,-1,sizeof(head));
        memset(dfn,0,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(cut,0,sizeof(cut));
        n=0,tot=0,cnt=0;
    }
    int main(){
        int u,v,sign=1;
        while(~scanf("%d",&u)&&u){
            init();
            n=max(n,u);
            while(scanf("%d",&v)){
                n=max(n,v);
                addedge(u,v);
                addedge(v,u);
                scanf("%d",&u);
                n=max(n,u);
                if(!u)
                    break;
            }
            
            for(int i=1;i<=n;i++)
                if(!dfn[i])
                    rt=i,tarjan(i);
            printf("Network #%d
    ",sign++);
            int flag=0;
            for(int i=1;i<=n;i++){
                if(cut[i]){
                    flag=1;
                    printf("  SPF node %d leaves %d subnets
    ",i,1+cut[i]);
                }
            }
            if(!flag)
                printf("  No SPF nodes
    ");
            putchar('
    ');
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Django rest_framework之序列化(serializers)
    异常处理
    Django之ModelForm通过ajax用户登录验证
    Django之ModelForm用户登录注册
    Django之Model操作
    Jenkins+Maven+SVN+Nexus 搭建持续集成环境
    nginx rewrite域名跳转访问XML接口
    python自动发布应用脚本
    Django基础
    Web安全概述
  • 原文地址:https://www.cnblogs.com/starve/p/10956558.html
Copyright © 2020-2023  润新知