割边模板

判断方面,没有了割点的root的特判,并且==号去掉

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn=1e3+10;
 7 
 8 int dfn[maxn],low[maxn],head[maxn],vis[maxn];
 9 bool judge[maxn];
10 int k,n,m,num,root;
11 struct Edge{
12     int to,next;
13 }G[400010];
14 struct node
15 {
16     int u,v;
17 }sto[maxn]; int cot;
18 //这个大小应该跟边数同步,但这里跟点的个数同步也能过;
19 //大概是因为割边的数量不多吧
20 void build(int u,int v){
21     G[num].to=v;G[num].next=head[u];head[u]=num++;
22 }
23 
24 void Tarjan(int u,int fa){
25     int son=0;
26     vis[u]=1;    //判断是否访问过,当访问完后定为2,不再访问;
27     k++;
28     dfn[u]=k;    //当前顶点的时间戳
29     low[u]=k;    //当前顶点能够访问到的最小时间戳 一开始是自己
30     for(int i=head[u];i!=-1;i=G[i].next){
31         int v=G[i].to;
32         //如果定点i曾经被访问过,并且这个定点不是当前u的父亲,就说明
33         //此时的i为U的祖先,所以更新u的权值
34         if(vis[v]==1&&v!=fa)
35             low[u]=min(low[u],dfn[v]);
36         if(vis[v]==0){
37             Tarjan(v,u);
38             son++;
39             //更新当前顶点u能访问到的最早顶点的时间戳;
40             low[u]=min(low[u],low[v]);
41             //如果是根节点,就必须要有两个儿子才会使割点;
42             //不是根节点,就要满足dfn[u]<=low[v]
43             if(dfn[u]<low[v]){
44                 cot++;
45                 if(u<v) sto[cot].u=u-1,sto[cot].v=v-1;
46                 else    sto[cot].u=v-1,sto[cot].v=u-1;
47             }
48         }
49     }
50     vis[u]=2;
51 }
52 bool cmp(node a,node b)
53 {
54     if(a.u==b.u) return a.v<b.v;
55     else return a.u<b.u;
56 }
57 int main(){
58     while(scanf("%d%d",&n,&m)!=EOF){
59         memset(head,-1,sizeof(head));
60         memset(dfn,0,sizeof(dfn));
61         memset(low,0,sizeof(low));
62         memset(vis,0,sizeof(vis));
63         memset(judge,0,sizeof(judge));
64         num=0;cot=0;
65         int u,v;
66         for(int i=1;i<=m;i++){
67             scanf("%d%d",&u,&v);
68             u++;v++;
69             build(u,v);
70             build(v,u);
71         }
72         root=1;
73         Tarjan(root,-1);
74         printf("%d\n",cot);
75         if(!cot) printf("\n");
76         else{
77             sort(sto+1,sto+1+cot,cmp);
78             for(int i=1;i<=cot;i++)
79                 printf("%d %d\n",sto[i].u,sto[i].v);
80             printf("\n");
81         }
82     }
83     return 0;
84 }

 

posted @ 2019-11-13 20:29  古比  阅读(147)  评论(0编辑  收藏  举报