• ZOJ 2588


    求一个无向图的桥(可能存在重边),输出割边的数目,并按顺序输出割边的序号(输入的顺序)。

    由于内存的限制 , 无法使用邻接矩阵 , 只能用邻接表了 .

    第一次用了邻接表,超内存了;

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <string.h>
     5 using namespace std;
     6 const int N=10002;
     7 const int M=1000002;
     8 struct edge{
     9     int v,next,id,two=0;
    10 }e[M];
    11 int k,first[M],id,count1;                          //first[i]是以点i为起点的链表头部
    12 int dfn[N],low[N],bri[M],mun;
    13 void init(){
    14     k=1;
    15     count1=0;
    16     mun=0;
    17     id=0;
    18     memset(first,0,sizeof(first));
    19     memset(low,0,sizeof(low));
    20     memset(dfn,0,sizeof(dfn));
    21     memset(bri,0,sizeof(bri));
    22 }
    23 void addedge(int a,int b){                        //向图中加边的算法,注意加上的是有向边//b为a的后续节点既是a---->b
    24     int i;
    25     for(i=first[a];i;i=e[i].next){
    26         if(e[i].v==b)break;
    27     }
    28     if(i){                                         //方法稍作修改,用来标注重边
    29         e[i].two=1;
    30         return ;
    31     }
    32     e[k].v=b;
    33     e[k].next=first[a];
    34     e[k].id=id;
    35     e[k].two=0;
    36     first[a]=k++;
    37 }
    38 void dfs(int u,int far){                           //dfn,Tarjan算法 
    39     dfn[u]=low[u]=++count1;
    40     for(int i=first[u];i;i=e[i].next){
    41         int v=e[i].v;
    42         if(!dfn[v]){
    43             dfs(v,u);
    44             low[u]=min(low[u],low[v]);
    45             if(low[v]>dfn[u]&&!e[i].two){
    46                 bri[mun++]=e[i].id;
    47             }
    48 
    49         }
    50         else if(v!=far)low[u]=min(low[u],dfn[v]);
    51     }
    52 }
    53 void print(){
    54     printf("%d
    ",mun);
    55     if(mun>0){
    56         sort(bri,bri+mun);
    57         printf("%d",bri[0]);
    58         for(int i=1;i<mun;i++)
    59             printf(" %d",bri[i]);
    60         printf("
    ");
    61     }
    62 }
    63 int main(){
    64     int t,n,m,a,b;
    65     scanf("%d",&t);
    66     while(t--){
    67         init();
    68         scanf("%d%d",&n,&m);
    69         while(m--){
    70             scanf("%d%d",&a,&b);
    71             id++;
    72             addedge(a,b);
    73             addedge(b,a);
    74         }
    75         dfs(1,0);
    76         print();
    77         if(t)printf("
    ");
    78     }
    79     return 0;
    80 }

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <string.h>
    using namespace std;
    const int N=10002;
    const int M=1000002;
    struct edge{
        int v,next,id,two=0;
    }e[M];
    int k,first[M],id,count1;
    int dfn[N],low[N],bri[M],mun;
    void init(){
        k=1;
        count1=0;
        mun=0;
        id=0;
        memset(first,0,sizeof(first));
        memset(low,0,sizeof(low));
        memset(dfn,0,sizeof(dfn));
        memset(bri,0,sizeof(bri));
    }
    void addedge(int a,int b){
        int i;
        for(i=first[a];i;i=e[i].next){
            if(e[i].v==b)break;
        }
        if(i){
            e[i].two=1;
            return ;
        }
        e[k].v=b;
        e[k].next=first[a];
        e[k].id=id;
        e[k].two=0;
        first[a]=k++;
    }
    void dfs(int u,int far){
        dfn[u]=low[u]=++count1;
        for(int i=first[u];i;i=e[i].next){
            int v=e[i].v;
            if(!dfn[v]){
                dfs(v,u);
                low[u]=min(low[u],low[v]);
                if(low[v]>dfn[u]&&!e[i].two){
                    bri[mun++]=e[i].id;
                }

            }
            else if(v!=far)low[u]=min(low[u],dfn[v]);
        }
    }
    void print(){
        printf("%d ",mun);
        if(mun>0){
            sort(bri,bri+mun);
            printf("%d",bri[0]);
            for(int i=1;i<mun;i++)
                printf(" %d",bri[i]);
            printf(" ");
        }
    }
    int main(){
        int t,n,m,a,b;
        scanf("%d",&t);
        while(t--){
            init();
            scanf("%d%d",&n,&m);
            while(m--){
                scanf("%d%d",&a,&b);
                id++;
                addedge(a,b);
                addedge(b,a);
            }
            dfs(1,0);
            print();
            if(t)printf(" ");
        }
        return 0;
    }

  • 相关阅读:
    后台点赞 接口
    三表联查
    后台投票 接口
    MSXML insertBefore(IXMLDOMNode *newChild, VARIANT refChild) 传参
    WTL中菜单栏及工具栏项状态改变应注意的地方
    使用WTL的消息反射封装CEdit实现监听控件文本改变事件
    修改字体
    CEdit实现文本换行
    VC中获取窗口控件相对客户区的坐标
    关闭HTC手机充电时屏幕一直亮着绿色电池的办法
  • 原文地址:https://www.cnblogs.com/Mr-Xu-JH/p/3900251.html
Copyright © 2020-2023  润新知