12:
着实写了好久 ,虽然一直照着别人的思路,一直TLE
思路:这题求无向图的桥
用targan求桥时有这样一个性质 low[v]<dfn[u] 时 u是割点 那么 u-v这条边是桥。
证明:在
图论算法理论、实现及应用
王桂平、王 衍、任嘉辰 编著
420 面有证明
后面利用LCA 暴力即可 因为询问次数不多 。
LCA (u,v)若两者在同一个缩点里面的话桥数不变。
否则 两者的缩点里面的桥都没有了
1 #include<cstdio>
2 #include<iostream>
3 #include<vector>
4 #include<stack>
5 #include<algorithm>
6 #include< string.h>
7
8 using namespace std;
9
10 #define N 100100
11 #define M 200100
12
13 int dfn[N],low[N],is_bridge[N],dfs_clock;
14 int fa[N];
15 int vis[N];
16 int head[N];
17 struct Edge{
18 int v,next;
19 }edge[M* 2];
20
21 int ans,cnt;
22 int n,m;
23
24 void dfs( int u, int f)
25 {
26 dfn[u]=low[u]=++dfs_clock;
27 // vis[u]=1;
28 // fa[u]=f;
29 for ( int i=head[u];i!=- 1;i=edge[i].next)
30 {
31 int v=edge[i].v;;
32 if (v==f) continue;
33 // fa[v]=u;
34 if (dfn[v]==- 1)
35 {
36 fa[v]=u; // 因为这个位置TL很多次
37 dfs(v,u);
38 low[u]=min(low[u],low[v]);
39 if (low[v]>dfn[u])
40 {
41 ans++;
42 is_bridge[v]= 1;
43 }
44 }
45 else low[u]=min(low[u],dfn[v]);
46 }
47 }
48
49 void LCA( int u, int v)
50 {
51 if (dfn[u]>dfn[v]) swap(u,v);
52 while (dfn[u]<dfn[v])
53 {
54 if (is_bridge[v])
55 {
56 ans--;
57 is_bridge[v]= 0;
58 }
59 v=fa[v];
60 }
61 while (u!=v)
62 {
63 if (is_bridge[u])
64 {
65 ans--;
66 is_bridge[u]= 0;
67 }
68 u=fa[u];
69 if (is_bridge[v])
70 {
71 ans--;
72 is_bridge[v]= 0;
73 }
74 v=fa[v];
75 }
76 }
77 void add( int u, int v)
78 {
79 edge[cnt].v=v;
80 edge[cnt].next=head[u];
81 head[u]=cnt++;
82 edge[cnt].v=u;
83 edge[cnt].next=head[v];
84 head[v]=cnt++;
85 }
86
87 void init()
88 {
89 dfs_clock= 0;
90 ans=cnt= 0;
91 memset(is_bridge, 0, sizeof(is_bridge));
92 // memset(vis,0,sizeof(vis));
93 memset(head,- 1, sizeof(head));
94 memset(dfn,- 1, sizeof(dfn));
95 for ( int i= 1;i<=n;i++) fa[i]=i;
96 // for (int i=0;i<=n;i++) mp[i].clear();
97 }
98
99 int main()
100 {
101 int cas= 0;
102 // freopen("input.txt","r",stdin);
103 // freopen("out.txt","w",stdout);
104 while (scanf( " %d%d ",&n,&m)!=EOF)
105 {
106 if (n== 0&&m== 0) break;
107 init();
108 for ( int i= 0;i<m;i++)
109 {
110 int u,v;
111 scanf( " %d%d ",&u,&v);
112 // mp[u].push_back(v);
113 // mp[v].push_back(u);
114 add(u,v);
115 }
116
117 dfs( 1, 0);
118 int Q;
119 scanf( " %d ",&Q);
120 printf( " Case %d:\n ",++cas);
121 while (Q--)
122 {
123 int u,v;
124 scanf( " %d%d ",&u,&v);
125 LCA(u,v);
126 printf( " %d\n ",ans);
127 }
128 puts( "");
129 }
130 return 0;
131 }
3 #include<vector>
4 #include<stack>
5 #include<algorithm>
6 #include< string.h>
7
8 using namespace std;
9
10 #define N 100100
11 #define M 200100
12
13 int dfn[N],low[N],is_bridge[N],dfs_clock;
14 int fa[N];
15 int vis[N];
16 int head[N];
17 struct Edge{
18 int v,next;
19 }edge[M* 2];
20
21 int ans,cnt;
22 int n,m;
23
24 void dfs( int u, int f)
25 {
26 dfn[u]=low[u]=++dfs_clock;
27 // vis[u]=1;
28 // fa[u]=f;
29 for ( int i=head[u];i!=- 1;i=edge[i].next)
30 {
31 int v=edge[i].v;;
32 if (v==f) continue;
33 // fa[v]=u;
34 if (dfn[v]==- 1)
35 {
36 fa[v]=u; // 因为这个位置TL很多次
37 dfs(v,u);
38 low[u]=min(low[u],low[v]);
39 if (low[v]>dfn[u])
40 {
41 ans++;
42 is_bridge[v]= 1;
43 }
44 }
45 else low[u]=min(low[u],dfn[v]);
46 }
47 }
48
49 void LCA( int u, int v)
50 {
51 if (dfn[u]>dfn[v]) swap(u,v);
52 while (dfn[u]<dfn[v])
53 {
54 if (is_bridge[v])
55 {
56 ans--;
57 is_bridge[v]= 0;
58 }
59 v=fa[v];
60 }
61 while (u!=v)
62 {
63 if (is_bridge[u])
64 {
65 ans--;
66 is_bridge[u]= 0;
67 }
68 u=fa[u];
69 if (is_bridge[v])
70 {
71 ans--;
72 is_bridge[v]= 0;
73 }
74 v=fa[v];
75 }
76 }
77 void add( int u, int v)
78 {
79 edge[cnt].v=v;
80 edge[cnt].next=head[u];
81 head[u]=cnt++;
82 edge[cnt].v=u;
83 edge[cnt].next=head[v];
84 head[v]=cnt++;
85 }
86
87 void init()
88 {
89 dfs_clock= 0;
90 ans=cnt= 0;
91 memset(is_bridge, 0, sizeof(is_bridge));
92 // memset(vis,0,sizeof(vis));
93 memset(head,- 1, sizeof(head));
94 memset(dfn,- 1, sizeof(dfn));
95 for ( int i= 1;i<=n;i++) fa[i]=i;
96 // for (int i=0;i<=n;i++) mp[i].clear();
97 }
98
99 int main()
100 {
101 int cas= 0;
102 // freopen("input.txt","r",stdin);
103 // freopen("out.txt","w",stdout);
104 while (scanf( " %d%d ",&n,&m)!=EOF)
105 {
106 if (n== 0&&m== 0) break;
107 init();
108 for ( int i= 0;i<m;i++)
109 {
110 int u,v;
111 scanf( " %d%d ",&u,&v);
112 // mp[u].push_back(v);
113 // mp[v].push_back(u);
114 add(u,v);
115 }
116
117 dfs( 1, 0);
118 int Q;
119 scanf( " %d ",&Q);
120 printf( " Case %d:\n ",++cas);
121 while (Q--)
122 {
123 int u,v;
124 scanf( " %d%d ",&u,&v);
125 LCA(u,v);
126 printf( " %d\n ",ans);
127 }
128 puts( "");
129 }
130 return 0;
131 }