求一个无向图的桥(可能存在重边),输出割边的数目,并按顺序输出割边的序号(输入的顺序)。
由于有重边,一般需要使用邻接表来存储,我一开始嫌麻烦,想使用邻接矩阵和边集来存,没注意到节点数目太大,结果MLE。最终还是得用邻接表,写好后,有贡献了一次PE,改正格式后居然WA了,经检查在插入边时有点问题,插入时要先查找该边是否已出现,当初使用的是if(findEdge(a,b)==0&&findEdge(b,a)==0)来判断边是否已插入,后来发现这个不能保证findEdge(a,b)和findEdge(b,a)都会执行,改成if(findEdge(a,b)+findEdge(a,b))就AC了。但至今不解当初为何会PE,OJ是按怎样的顺序判错的呢?
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <memory.h>
4 #define MIN(a,b) ((a)<(b)?(a):(b))
5 #define N 10001
6 struct node
7 {
8 int v,id,cnt;
9 struct node *next;
10 };
11 struct node *list[N];
12 char vis[N];
13 int dfn[N],low[N],father[N],n,m,id,ans[N],num;
14 int findEdge(int u,int v)
15 {
16 struct node *p=list[u];
17 while(p)
18 {
19 if(p->v==v)
20 {
21 p->cnt++;
22 return 1;
23 }
24 p=p->next;
25 }
26 return 0;
27 }
28 void addEdge(int u,int v,int id)
29 {
30 struct node *p=(struct node*)malloc(sizeof(struct node));
31 p->id=id;
32 p->v=v;
33 p->next=0;
34 p->cnt=1;
35 if(list[u])
36 {
37 p->next=list[u];
38 list[u]=p;
39 }
40 else list[u]=p;
41 }
42 void init()
43 {
44 memset(vis,0,sizeof(vis));
45 memset(father,0,sizeof(father));
46 dfn[1]=low[1]=id=1;
47 vis[1]=1;
48 num=0;
49 }
50 void dfs(int u)
51 {
52 int v;
53 struct node *p=list[u];
54 while(p)
55 {
56 v=p->v;
57 if(father[u]!=v)
58 {
59 if(vis[v]) low[u]=MIN(low[u],dfn[v]);
60 else
61 {
62 father[v]=u;
63 vis[v]=1;
64 id++;
65 dfn[v]=low[v]=id;
66 dfs(v);
67 low[u]=MIN(low[v],low[u]);
68 if(dfn[u]<low[v]&&p->cnt==1)
69 {
70 ans[num++]=p->id;
71 }
72 }
73 }
74 p=p->next;
75 }
76 }
77 int cmp(const void *a,const void *b)
78 {
79 return *(int *)a-*(int *)b;
80 }
81 int main()
82 {
83 int i,t,a,b,f;
84 struct node *p;
85 freopen("in.txt","r",stdin);
86 scanf("%d",&t);
87 while(t--)
88 {
89 scanf("%d%d",&n,&m);
90 for(i=1; i<=m; i++)
91 {
92 scanf("%d%d",&a,&b);
93 f=findEdge(a,b)+findEdge(b,a);
94 if(!f)
95 {
96 addEdge(a,b,i);
97 addEdge(b,a,i);
98 }
99 }
100 init();
101 dfs(1);
102 qsort(ans,num,sizeof(ans[0]),cmp);
103 printf("%d\n",num);
104 if(num)
105 {
106 printf("%d",ans[0]);
107 for(i=1; i<num; i++) printf(" %d",ans[i]);
108 printf("\n");
109 }
110 if(t) printf("\n");
111 for(i=1; i<=n; i++)
112 {
113 p=list[i];
114 while(p)
115 {
116 list[i]=p->next;
117 free(p);
118 p=list[i];
119 }
120 }
121 }
122 return 0;
123 }