[POJ3694]Network(LCA, 割边, 桥)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[POJ3694]Network(LCA, 割边, 桥)相关的知识,希望对你有一定的参考价值。

题目链接:http://poj.org/problem?id=3694

题意:给一张图,每次加一条边,问割边数量。

tarjan先找出所有割边,并且记录每个点的父亲和来自于哪一条边,然后询问的时候从两个点向上找lca,沿途更新割边数量和割边状态即可。

 

AC代码

  1 /*
  2             ━━━━━┒ギリギリ♂ eye!
  3             ┓┏┓┏┓┃キリキリ♂ mind!
  4             ┛┗┛┗┛┃\○/
  5             ┓┏┓┏┓┃ /
  6             ┛┗┛┗┛┃ノ)
  7             ┓┏┓┏┓┃
  8             ┛┗┛┗┛┃
  9             ┓┏┓┏┓┃
 10             ┛┗┛┗┛┃
 11             ┓┏┓┏┓┃
 12             ┛┗┛┗┛┃
 13             ┓┏┓┏┓┃
 14             ┃┃┃┃┃┃
 15             ┻┻┻┻┻┻
 16 */
 17 #include                     <algorithm>
 18 #include                     <iostream>
 19 #include                     <iomanip>
 20 #include                     <cstring>
 21 #include                     <climits>
 22 #include                     <complex>
 23 #include                     <fstream>
 24 #include                     <cassert>
 25 #include                     <cstdio>
 26 #include                     <bitset>
 27 #include                     <vector>
 28 #include                     <deque>
 29 #include                     <queue>
 30 #include                     <stack>
 31 #include                     <ctime>
 32 #include                     <set>
 33 #include                     <map>
 34 #include                     <cmath>
 35 using namespace             std;
 36 #define fr                     first
 37 #define sc                     second
 38 #define cl                     clear
 39 #define BUG                 puts("here!!!")
 40 #define W(a)                 while(a--)
 41 #define pb(a)                 push_back(a)
 42 #define Rint(a)             scanf("%d", &a)
 43 #define Rll(a)                 scanf("%lld", &a)
 44 #define Rs(a)                 scanf("%s", a)
 45 #define Cin(a)                 cin >> a
 46 #define FRead()             freopen("in", "r", stdin)
 47 #define FWrite()             freopen("out", "w", stdout)
 48 #define Rep(i, len)         for(int i = 0; i < (len); i++)
 49 #define For(i, a, len)         for(int i = (a); i < (len); i++)
 50 #define Cls(a)                 memset((a), 0, sizeof(a))
 51 #define Clr(a, x)             memset((a), (x), sizeof(a))
 52 #define Full(a)             memset((a), 0x7f7f, sizeof(a))
 53 #define lp                    p << 1
 54 #define rp                    p << 1 | 1
 55 #define pi                    3.14159265359
 56 #define RT                    return
 57 typedef    long long             LL;
 58 typedef    long double         LD;
 59 typedef    unsigned long long     ULL;
 60 typedef    pair<int, int>         pii;
 61 typedef    pair<string, int>     psi;
 62 typedef    map<string, int>     msi;
 63 typedef    vector<int>         vi;
 64 typedef    vector<LL>             vl;
 65 typedef    vector<vl>             vvl;
 66 typedef    vector<bool>         vb;
 67 
 68 inline bool scan_d(int &num) {
 69     char in;bool IsN=false;
 70     in=getchar();
 71     if(in==EOF) return false;
 72     while(in!=-&&(in<0||in>9)) in=getchar();
 73     if(in==-){ IsN=true;num=0;}
 74     else num=in-0;
 75     while(in=getchar(),in>=0&&in<=9){
 76             num*=10,num+=in-0;
 77     }
 78     if(IsN) num=-num;
 79     return true;
 80 }
 81 
 82 const int maxn = 200010;
 83 const int maxm = 900020;
 84 
 85 typedef struct Edge {
 86     int idx, v;
 87     Edge() {}
 88     Edge(int vv, int ii) : v(vv), idx(ii) {}
 89 }Edge;
 90 
 91 int n, m, q, cnt, b;
 92 int depth[maxn], fa[maxn], vis[maxn];
 93 int dfn[maxn], low[maxn], pbr[maxm];
 94 vector<Edge> G[maxn];
 95 bool bri[maxm];
 96 void dfs(int u, int p, int d) {
 97     fa[u] = p; depth[u] = d;
 98     Rep(i, G[u].size()) {
 99         int v = G[u][i].v;
100         if(!vis[v]) {
101             vis[v] = 1;
102             dfs(v, u, d+1);
103         }
104     }
105 }
106 
107 void tarjan(int u, int p, int d, int pe) {
108     low[u] = dfn[u] = d;
109     pbr[u] = pe;
110     Rep(i, G[u].size()) {
111         int idx = G[u][i].idx;
112         int v = G[u][i].v;
113         if(!dfn[v]) {
114             tarjan(v, u, d+1, idx);
115             low[u] = min(low[u], low[v]);
116             if(low[v] > dfn[u]) bri[idx] = 1;
117         }
118         else if(v != p) low[u] = min(low[u], dfn[v]);
119     }
120 }
121 
122 void lca(int u, int v) {
123     while(depth[u] > depth[v]) {
124         if(bri[pbr[u]]) {
125             bri[pbr[u]] = 0; b--;
126         }
127         u = fa[u];
128     }
129     while(depth[v] > depth[u]) {
130         if(bri[pbr[v]]) {
131             bri[pbr[v]] = 0; b--;
132         }
133         v = fa[v];
134     }
135     while(u != v) {
136         if(bri[pbr[u]]) {
137             bri[pbr[u]] = 0; b--;
138         }
139         u = fa[u];
140         if(bri[pbr[v]]) {
141             bri[pbr[v]] = 0; b--;
142         }
143         v = fa[v];
144     }
145 }
146 
147 int main() {
148     // FRead();
149     int u, v, _ = 1;
150     while(~scan_d(n) && ~scan_d(m) && n + m) {
151         Cls(depth); Cls(vis); Cls(fa); Cls(pbr);
152         Cls(dfn); Cls(low); Cls(bri); b = 0;
153         Rep(i, n+5) G[i].cl();
154         Rep(i, m) {
155             scan_d(u); scan_d(v);
156             G[u].pb(Edge(v, cnt++)); G[v].pb(Edge(u, cnt++));
157         }
158         dfs(1, 1, 0); tarjan(1, 1, 0, 0);
159         scan_d(q);
160         printf("Case %d:\n", _++);
161         For(i, 1, cnt+1) if(bri[i]) b++;
162         W(q) {
163             scan_d(u); scan_d(v);
164             lca(u, v);
165             printf("%d\n", b);
166         }
167     }
168     RT 0;
169 }

 

 

第一次TLE了,因为窝把erase的复杂度想象成了O(lgn)…

  1 /*
  2             ━━━━━┒ギリギリ♂ eye!
  3             ┓┏┓┏┓┃キリキリ♂ mind!
  4             ┛┗┛┗┛┃\○/
  5             ┓┏┓┏┓┃ /
  6             ┛┗┛┗┛┃ノ)
  7             ┓┏┓┏┓┃
  8             ┛┗┛┗┛┃
  9             ┓┏┓┏┓┃
 10             ┛┗┛┗┛┃
 11             ┓┏┓┏┓┃
 12             ┛┗┛┗┛┃
 13             ┓┏┓┏┓┃
 14             ┃┃┃┃┃┃
 15             ┻┻┻┻┻┻
 16 */
 17 #include                     <algorithm>
 18 #include                     <iostream>
 19 #include                     <iomanip>
 20 #include                     <cstring>
 21 #include                     <climits>
 22 #include                     <complex>
 23 #include                     <fstream>
 24 #include                     <cassert>
 25 #include                     <cstdio>
 26 #include                     <bitset>
 27 #include                     <vector>
 28 #include                     <deque>
 29 #include                     <queue>
 30 #include                     <stack>
 31 #include                     <ctime>
 32 #include                     <set>
 33 #include                     <map>
 34 #include                     <cmath>
 35 using namespace             std;
 36 #define fr                     first
 37 #define sc                     second
 38 #define cl                     clear
 39 #define BUG                 puts("here!!!")
 40 #define W(a)                 while(a--)
 41 #define pb(a)                 push_back(a)
 42 #define Rint(a)             scanf("%d", &a)
 43 #define Rll(a)                 scanf("%lld", &a)
 44 #define Rs(a)                 scanf("%s", a)
 45 #define Cin(a)                 cin >> a
 46 #define FRead()             freopen("in", "r", stdin)
 47 #define FWrite()             freopen("out", "w", stdout)
 48 #define Rep(i, len)         for(int i = 0; i < (len); i++)
 49 #define For(i, a, len)         for(int i = (a); i < (len); i++)
 50 #define Cls(a)                 memset((a), 0, sizeof(a))
 51 #define Clr(a, x)             memset((a), (x), sizeof(a))
 52 #define Full(a)             memset((a), 0x7f7f, sizeof(a))
 53 #define lp                    p << 1
 54 #define rp                    p << 1 | 1
 55 #define pi                    3.14159265359
 56 #define RT                    return
 57 typedef    long long             LL;
 58 typedef    long double         LD;
 59 typedef    unsigned long long     ULL;
 60 typedef    pair<int, int>         pii;
 61 typedef    pair<string, int>     psi;
 62 typedef    map<string, int>     msi;
 63 typedef    vector<int>         vi;
 64 typedef    vector<LL>             vl;
 65 typedef    vector<vl>             vvl;
 66 typedef    vector<bool>         vb;
 67 
 68 inline bool scan_d(int &num) {
 69     char in;bool IsN=false;
 70     in=getchar();
 71     if(in==EOF) return false;
 72     while(in!=-&&(in<0||in>9)) in=getchar();
 73     if(in==-){ IsN=true;num=0;}
 74     else num=in-0;
 75     while(in=getchar(),in>=0&&in<=9){
 76             num*=10,num+=in-0;
 77     }
 78     if(IsN) num=-num;
 79     return true;
 80 }
 81 
 82 const int maxn = 100010;
 83 const int maxm = 300020;
 84 typedef struct Bridge {
 85     int u, v;
 86     Bridge() {}
 87     Bridge(int uu, int vv) : u(uu), v(vv) { if(u > v) swap(u, v); }
 88     bool operator<(Bridge y) {
 89         if(u == y.u) return v < y.v;
 90         return u < y.u;
 91     }
 92 }Bridge;
 93 
 94 int n, m, q;
 95 int ufs[maxn];
 96 int depth[maxn], fa[maxn], vis[maxn];
 97 int dfn[maxn], low[maxn];
 98 vi G[maxn];
 99 vector<Bridge> b;
100 vector<Bridge>::iterator it;
101 
102 int find(int x) {
103     return x == ufs[x] ? x : ufs[x] = find(ufs[x]);
104 }
105 
106 void unite(int x, int y) {
107     x = find(x);
108     y = find(y);
109     if(x != y) ufs[y] = x;
110 }
111 
112 void dfs(int u, int p, int d) {
113     fa[u] = p; depth[u] = d;
114     Rep(i, G[u].size()) {
115         int v = G[u][i];
116         if(!vis[v]) {
117             vis[v] = 1;
118             dfs(v, u, d+1);
119         }
120     }
121 }
122 
123 
124 void tarjan(int u, int p, int d) {
125     low[u] = dfn[u] = d;
126     Rep(i, G[u].size()) {
127         int v = G[u][i];
128         if(!dfn[v]) {
129             tarjan(v, u, d+1);
130             low[u] = min(low[u], low[v]);
131             if(low[v] > dfn[u]) b.pb(Bridge(u, v));
132         }
133         else if(v != p) low[u] = min(low[u], dfn[v]);
134     }
135 }
136 
137 bool cmp(Bridge x, Bridge y) {
138     if(x.u == y.u) return x.v < y.v;
139     return x.u < y.u;
140 }
141 
142 int bs(Bridge x) {
143     int lo = 0, hi = b.size();
144     while(lo <= hi) {
145         int mi = (lo + hi) >> 1;
146         if(b[mi].u == x.u && b[mi].v == x.v) return mi;
147         if(cmp(x, b[mi]) > 0) hi = mi - 1;
148         else lo = mi + 1;
149     }
150     if(b[lo].u == x.u && b[lo].v == x.v) return lo;
151     if(b[hi].u == x.u && b[hi].v == x.v) return hi;
152     return -1;
153 }
154 
155 void lca(int u, int v) {
156     while(depth[u] > depth[v]) {
157         Bridge tmp = Bridge(u, fa[u]);
158         it = lower_bound(b.begin(), b.end(), tmp);
159         if(it != b.end() && it->u == tmp.u && it->v == tmp.v) b.erase(it);
160         u = fa[u];
161     }
162     while(depth[v] > depth[u]) {
163         Bridge tmp = Bridge(v, fa[v]);
164         it = lower_bound(b.begin(), b.end(), tmp);
165         if(it != b.end() && it->u == tmp.u && it->v == tmp.v) b.erase(it);
166         v = fa[v];
167     }
168     while(u != v) {
169         Bridge tmp = Bridge(u, fa[u]);
170         it = lower_bound(b.begin(), b.end(), tmp);
171         if(it != b.end() && it->u == tmp.u && it->v == tmp.v) b.erase(it);
172         tmp = Bridge(v, fa[v]);
173         it = lower_bound(b.begin(), b.end(), tmp);
174         if(it != b.end() && it->u == tmp.u && it->v == tmp.v) b.erase(it);
175         u = fa[u];
176         v = fa[v];
177     }
178 }
179 
180 int main() {
181     // FRead();
182     int u, v, _ = 1;
183     while(~scan_d(n) && ~scan_d(m) && n + m) {
184         Cls(depth); Cls(vis); Cls(fa);
185         Cls(dfn); Cls(low); b.cl();
186         Rep(i, n+5) G[i].cl(), ufs[i] = i;
187         Rep(i, m) {
188             scan_d(u); scan_d(v);
189             G[u].pb(v); G[v].pb(u);
190         }
191         dfs(1, 1, 0); tarjan(1, 1, 0);
192         sort(b.begin(), b.end(), cmp);
193         scan_d(q);
194         printf("Case %d:\n", _++);
195         W(q) {
196             scan_d(u); scan_d(v);
197             Bridge tmp = Bridge(u, v);
198             it = lower_bound(b.begin(), b.end(), tmp);
199             if(it != b.end() && it->u == tmp.u && it->v == tmp.v) {
200                 b.erase(it);
201                 printf("%d\n", b.size());
202                 continue;
203             }
204             else {
205                 lca(u, v);
206                 printf("%d\n", b.size());
207             }
208         }
209     }
210     RT 0;
211 }

 

以上是关于[POJ3694]Network(LCA, 割边, 桥)的主要内容,如果未能解决你的问题,请参考以下文章

POJ 3694Network(Tarjan边双联通分量 + 缩点 + LCA并查集维护)

POJ 3694 Network (tarjan + LCA)

POJ3694 Network(Tarjan双联通分图 LCA 桥)

POJ 1236 Network of Schools(tarjan算法 + LCA)

poj3694(lca + tarjan求桥模板)

poj3694 双连通分量+lca