[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 桥)