[POJ3694]Network(LCA, 割边, 桥)
2016-05-23 07:27
363 查看
题目链接:http://poj.org/problem?id=3694
题意:给一张图,每次加一条边,问割边数量。
tarjan先找出所有割边,并且记录每个点的父亲和来自于哪一条边,然后询问的时候从两个点向上找lca,沿途更新割边数量和割边状态即可。
AC代码
第一次TLE了,因为窝把erase的复杂度想象成了O(lgn)…
题意:给一张图,每次加一条边,问割边数量。
tarjan先找出所有割边,并且记录每个点的父亲和来自于哪一条边,然后询问的时候从两个点向上找lca,沿途更新割边数量和割边状态即可。
AC代码
/* ━━━━━┒ギリギリ♂ eye! ┓┏┓┏┓┃キリキリ♂ mind! ┛┗┛┗┛┃\○/ ┓┏┓┏┓┃ / ┛┗┛┗┛┃ノ) ┓┏┓┏┓┃ ┛┗┛┗┛┃ ┓┏┓┏┓┃ ┛┗┛┗┛┃ ┓┏┓┏┓┃ ┛┗┛┗┛┃ ┓┏┓┏┓┃ ┃┃┃┃┃┃ ┻┻┻┻┻┻ */ #include <algorithm> #include <iostream> #include <iomanip> #include <cstring> #include <climits> #include <complex> #include <fstream> #include <cassert> #include <cstdio> #include <bitset> #include <vector> #include <deque> #include <queue> #include <stack> #include <ctime> #include <set> #include <map> #include <cmath> using namespace std; #define fr first #define sc second #define cl clear #define BUG puts("here!!!") #define W(a) while(a--) #define pb(a) push_back(a) #define Rint(a) scanf("%d", &a) #define Rll(a) scanf("%lld", &a) #define Rs(a) scanf("%s", a) #define Cin(a) cin >> a #define FRead() freopen("in", "r", stdin) #define FWrite() freopen("out", "w", stdout) #define Rep(i, len) for(int i = 0; i < (len); i++) #define For(i, a, len) for(int i = (a); i < (len); i++) #define Cls(a) memset((a), 0, sizeof(a)) #define Clr(a, x) memset((a), (x), sizeof(a)) #define Full(a) memset((a), 0x7f7f, sizeof(a)) #define lp p << 1 #define rp p << 1 | 1 #define pi 3.14159265359 #define RT return typedef long long LL; typedef long double LD; typedef unsigned long long ULL; typedef pair<int, int> pii; typedef pair<string, int> psi; typedef map<string, int> msi; typedef vector<int> vi; typedef vector<LL> vl; typedef vector<vl> vvl; typedef vector<bool> vb; inline bool scan_d(int &num) { char in;bool IsN=false; in=getchar(); if(in==EOF) return false; while(in!='-'&&(in<'0'||in>'9')) in=getchar(); if(in=='-'){ IsN=true;num=0;} else num=in-'0'; while(in=getchar(),in>='0'&&in<='9'){ num*=10,num+=in-'0'; } if(IsN) num=-num; return true; } const int maxn = 200010; const int maxm = 900020; typedef struct Edge { int idx, v; Edge() {} Edge(int vv, int ii) : v(vv), idx(ii) {} }Edge; int n, m, q, cnt, b; int depth[maxn], fa[maxn], vis[maxn]; int dfn[maxn], low[maxn], pbr[maxm]; vector<Edge> G[maxn]; bool bri[maxm]; void dfs(int u, int p, int d) { fa[u] = p; depth[u] = d; Rep(i, G[u].size()) { int v = G[u][i].v; if(!vis[v]) { vis[v] = 1; dfs(v, u, d+1); } } } void tarjan(int u, int p, int d, int pe) { low[u] = dfn[u] = d; pbr[u] = pe; Rep(i, G[u].size()) { int idx = G[u][i].idx; int v = G[u][i].v; if(!dfn[v]) { tarjan(v, u, d+1, idx); low[u] = min(low[u], low[v]); if(low[v] > dfn[u]) bri[idx] = 1; } else if(v != p) low[u] = min(low[u], dfn[v]); } } void lca(int u, int v) { while(depth[u] > depth[v]) { if(bri[pbr[u]]) { bri[pbr[u]] = 0; b--; } u = fa[u]; } while(depth[v] > depth[u]) { if(bri[pbr[v]]) { bri[pbr[v]] = 0; b--; } v = fa[v]; } while(u != v) { if(bri[pbr[u]]) { bri[pbr[u]] = 0; b--; } u = fa[u]; if(bri[pbr[v]]) { bri[pbr[v]] = 0; b--; } v = fa[v]; } } int main() { // FRead(); int u, v, _ = 1; while(~scan_d(n) && ~scan_d(m) && n + m) { Cls(depth); Cls(vis); Cls(fa); Cls(pbr); Cls(dfn); Cls(low); Cls(bri); b = 0; Rep(i, n+5) G[i].cl(); Rep(i, m) { scan_d(u); scan_d(v); G[u].pb(Edge(v, cnt++)); G[v].pb(Edge(u, cnt++)); } dfs(1, 1, 0); tarjan(1, 1, 0, 0); scan_d(q); printf("Case %d:\n", _++); For(i, 1, cnt+1) if(bri[i]) b++; W(q) { scan_d(u); scan_d(v); lca(u, v); printf("%d\n", b); } } RT 0; }
第一次TLE了,因为窝把erase的复杂度想象成了O(lgn)…
/* ━━━━━┒ギリギリ♂ eye! ┓┏┓┏┓┃キリキリ♂ mind! ┛┗┛┗┛┃\○/ ┓┏┓┏┓┃ / ┛┗┛┗┛┃ノ) ┓┏┓┏┓┃ ┛┗┛┗┛┃ ┓┏┓┏┓┃ ┛┗┛┗┛┃ ┓┏┓┏┓┃ ┛┗┛┗┛┃ ┓┏┓┏┓┃ ┃┃┃┃┃┃ ┻┻┻┻┻┻ */ #include <algorithm> #include <iostream> #include <iomanip> #include <cstring> #include <climits> #include <complex> #include <fstream> #include <cassert> #include <cstdio> #include <bitset> #include <vector> #include <deque> #include <queue> #include <stack> #include <ctime> #include <set> #include <map> #include <cmath> using namespace std; #define fr first #define sc second #define cl clear #define BUG puts("here!!!") #define W(a) while(a--) #define pb(a) push_back(a) #define Rint(a) scanf("%d", &a) #define Rll(a) scanf("%lld", &a) #define Rs(a) scanf("%s", a) #define Cin(a) cin >> a #define FRead() freopen("in", "r", stdin) #define FWrite() freopen("out", "w", stdout) #define Rep(i, len) for(int i = 0; i < (len); i++) #define For(i, a, len) for(int i = (a); i < (len); i++) #define Cls(a) memset((a), 0, sizeof(a)) #define Clr(a, x) memset((a), (x), sizeof(a)) #define Full(a) memset((a), 0x7f7f, sizeof(a)) #define lp p << 1 #define rp p << 1 | 1 #define pi 3.14159265359 #define RT return typedef long long LL; typedef long double LD; typedef unsigned long long ULL; typedef pair<int, int> pii; typedef pair<string, int> psi; typedef map<string, int> msi; typedef vector<int> vi; typedef vector<LL> vl; typedef vector<vl> vvl; typedef vector<bool> vb; inline bool scan_d(int &num) { char in;bool IsN=false; in=getchar(); if(in==EOF) return false; while(in!='-'&&(in<'0'||in>'9')) in=getchar(); if(in=='-'){ IsN=true;num=0;} else num=in-'0'; while(in=getchar(),in>='0'&&in<='9'){ num*=10,num+=in-'0'; } if(IsN) num=-num; return true; } const int maxn = 100010; const int maxm = 300020; typedef struct Bridge { int u, v; Bridge() {} Bridge(int uu, int vv) : u(uu), v(vv) { if(u > v) swap(u, v); } bool operator<(Bridge y) { if(u == y.u) return v < y.v; return u < y.u; } }Bridge; int n, m, q; int ufs[maxn]; int depth[maxn], fa[maxn], vis[maxn]; int dfn[maxn], low[maxn]; vi G[maxn]; vector<Bridge> b; vector<Bridge>::iterator it; int find(int x) { return x == ufs[x] ? x : ufs[x] = find(ufs[x]); } void unite(int x, int y) { x = find(x); y = find(y); if(x != y) ufs[y] = x; } void dfs(int u, int p, int d) { fa[u] = p; depth[u] = d; Rep(i, G[u].size()) { int v = G[u][i]; if(!vis[v]) { vis[v] = 1; dfs(v, u, d+1); } } } void tarjan(int u, int p, int d) { low[u] = dfn[u] = d; Rep(i, G[u].size()) { int v = G[u][i]; if(!dfn[v]) { tarjan(v, u, d+1); low[u] = min(low[u], low[v]); if(low[v] > dfn[u]) b.pb(Bridge(u, v)); } else if(v != p) low[u] = min(low[u], dfn[v]); } } bool cmp(Bridge x, Bridge y) { if(x.u == y.u) return x.v < y.v; return x.u < y.u; } int bs(Bridge x) { int lo = 0, hi = b.size(); while(lo <= hi) { int mi = (lo + hi) >> 1; if(b[mi].u == x.u && b[mi].v == x.v) return mi; if(cmp(x, b[mi]) > 0) hi = mi - 1; else lo = mi + 1; } if(b[lo].u == x.u && b[lo].v == x.v) return lo; if(b[hi].u == x.u && b[hi].v == x.v) return hi; return -1; } void lca(int u, int v) { while(depth[u] > depth[v]) { Bridge tmp = Bridge(u, fa[u]); it = lower_bound(b.begin(), b.end(), tmp); if(it != b.end() && it->u == tmp.u && it->v == tmp.v) b.erase(it); u = fa[u]; } while(depth[v] > depth[u]) { Bridge tmp = Bridge(v, fa[v]); it = lower_bound(b.begin(), b.end(), tmp); if(it != b.end() && it->u == tmp.u && it->v == tmp.v) b.erase(it); v = fa[v]; } while(u != v) { Bridge tmp = Bridge(u, fa[u]); it = lower_bound(b.begin(), b.end(), tmp); if(it != b.end() && it->u == tmp.u && it->v == tmp.v) b.erase(it); tmp = Bridge(v, fa[v]); it = lower_bound(b.begin(), b.end(), tmp); if(it != b.end() && it->u == tmp.u && it->v == tmp.v) b.erase(it); u = fa[u]; v = fa[v]; } } int main() { // FRead(); int u, v, _ = 1; while(~scan_d(n) && ~scan_d(m) && n + m) { Cls(depth); Cls(vis); Cls(fa); Cls(dfn); Cls(low); b.cl(); Rep(i, n+5) G[i].cl(), ufs[i] = i; Rep(i, m) { scan_d(u); scan_d(v); G[u].pb(v); G[v].pb(u); } dfs(1, 1, 0); tarjan(1, 1, 0); sort(b.begin(), b.end(), cmp); scan_d(q); printf("Case %d:\n", _++); W(q) { scan_d(u); scan_d(v); Bridge tmp = Bridge(u, v); it = lower_bound(b.begin(), b.end(), tmp); if(it != b.end() && it->u == tmp.u && it->v == tmp.v) { b.erase(it); printf("%d\n", b.size()); continue; } else { lca(u, v); printf("%d\n", b.size()); } } } RT 0; }
相关文章推荐
- 针对苹果最新审核要求 为应用兼容IPv6
- 读书笔记 ------ 重构 第七章 在代码之间搬移特性
- 制作自己的gitBook 书籍
- tarjan求割点
- IIS负载均衡-Application Request Route详解第一篇: ARR介绍
- 结合Jexus + Kestrel 部署 asp.net core 生产环境
- tarjan求割点
- 读书笔记 ------ 重构 -> 在对象之间搬移特性
- 【BZOJ-2648&2716】SJY摆棋子&天使玩偶 KD Tree
- 【POJ 3070】Fibonacci(矩阵快速幂)
- 扯淡 | 程序员和豪车及阿玛尼
- 河南省ACM第一届第一题
- CSS3背景温故
- C语言预处理 编译 汇编 链接四个阶段
- flask + MongoDB 学习笔记(1) : MongoDB配置和使用
- Excel错误值总结
- leetcode #25 in cpp
- 第105讲 Spark Streaming电商广告点击综合案例在线点击统计实战项目第一天
- 【游戏】金融帝国2:金融帝国实验室(Capitalism Lab)市长模式DLC+简单教程
- ZYKeyboardUtil 全自动处理键盘遮挡事件