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\n",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("\n");
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("\n");
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\n",mun);
    if(mun>0){
        sort(bri,bri+mun);
        printf("%d",bri[0]);
        for(int i=1;i<mun;i++)
            printf(" %d",bri[i]);
        printf("\n");
    }
}
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("\n");
    }
    return 0;
}

posted @ 2014-08-08 22:12  Mr.XuJH  阅读(137)  评论(0编辑  收藏  举报