POJ 3694 Network
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 }
随性Code