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

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

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<''||in>'')) in=getchar();
if(in=='-'){ IsN=true;num=;}
else num=in-'';
while(in=getchar(),in>=''&&in<=''){
num*=,num+=in-'';
}
if(IsN) num=-num;
return true;
} const int maxn = ;
const int maxm = ; 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] = ;
dfs(v, u, d+);
}
}
} 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+, idx);
low[u] = min(low[u], low[v]);
if(low[v] > dfn[u]) bri[idx] = ;
}
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]] = ; b--;
}
u = fa[u];
}
while(depth[v] > depth[u]) {
if(bri[pbr[v]]) {
bri[pbr[v]] = ; b--;
}
v = fa[v];
}
while(u != v) {
if(bri[pbr[u]]) {
bri[pbr[u]] = ; b--;
}
u = fa[u];
if(bri[pbr[v]]) {
bri[pbr[v]] = ; b--;
}
v = fa[v];
}
} int main() {
// FRead();
int u, v, _ = ;
while(~scan_d(n) && ~scan_d(m) && n + m) {
Cls(depth); Cls(vis); Cls(fa); Cls(pbr);
Cls(dfn); Cls(low); Cls(bri); b = ;
Rep(i, n+) 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(, , ); tarjan(, , , );
scan_d(q);
printf("Case %d:\n", _++);
For(i, , cnt+) if(bri[i]) b++;
W(q) {
scan_d(u); scan_d(v);
lca(u, v);
printf("%d\n", b);
}
}
RT ;
}

第一次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<''||in>'')) in=getchar();
if(in=='-'){ IsN=true;num=;}
else num=in-'';
while(in=getchar(),in>=''&&in<=''){
num*=,num+=in-'';
}
if(IsN) num=-num;
return true;
} const int maxn = ;
const int maxm = ;
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] = ;
dfs(v, u, d+);
}
}
} 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+);
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 = , hi = b.size();
while(lo <= hi) {
int mi = (lo + hi) >> ;
if(b[mi].u == x.u && b[mi].v == x.v) return mi;
if(cmp(x, b[mi]) > ) hi = mi - ;
else lo = mi + ;
}
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 -;
} 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, _ = ;
while(~scan_d(n) && ~scan_d(m) && n + m) {
Cls(depth); Cls(vis); Cls(fa);
Cls(dfn); Cls(low); b.cl();
Rep(i, n+) G[i].cl(), ufs[i] = i;
Rep(i, m) {
scan_d(u); scan_d(v);
G[u].pb(v); G[v].pb(u);
}
dfs(, , ); tarjan(, , );
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 ;
}

[POJ3694]Network(LCA, 割边, 桥)的更多相关文章

  1. D - Network - poj3694(LCA求桥)

    题意:有一个网络有一些边相互连接,现在有Q次操作,求每次操作后的桥的个数 分析:开始竟然不知道还有LCA这么个东西....... *********************************** ...

  2. 【POJ 3694】 Network(割边&lt;桥&gt;+LCA)

    [POJ 3694] Network(割边+LCA) Network Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 7971 ...

  3. [POJ3694]Network(Tarjan,LCA)

    [POJ3694]Network Description A network administrator manages a large network. The network consists o ...

  4. HDU 4738——Caocao's Bridges——————【求割边/桥的最小权值】

     Caocao's Bridges Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u S ...

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

    链接:http://poj.org/problem?id=3694 题意:给定一个有向连通图,每次增加一条边,求剩下的桥的数量. 思路: 给定一个无向连通图,添加一条u->v的边,求此边对图剩余 ...

  6. POJ3694 Network —— 边双联通分量 + 缩点 + LCA + 并查集

    题目链接:https://vjudge.net/problem/POJ-3694 A network administrator manages a large network. The networ ...

  7. Network POJ - 3694 (LCA+tarjan+桥)

    题目链接:https://vjudge.net/problem/POJ-3694 具体思路:首先可以通过缩点的方式将整个图变成一个树,并且树的每条边是桥,但是我们可以利用dfn数组将整个图变成树,这样 ...

  8. POJ 3694——Network——————【连通图,LCA求桥】

    Network Time Limit:5000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Stat ...

  9. POJ 3694 Network (求桥,边双连通分支缩点,lca)

    Network Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 5619   Accepted: 1939 Descripti ...

随机推荐

  1. nginx error_page 404 用 php header 无法跳转

    nginx error_page 404 用 php header 无法跳转 之前用Apache的时候,只需要设置 ErrorDocument 404 /404.php 就可以在 404.php 中根 ...

  2. unity项目实现“再按一次退出程序”提示功能

    unity项目,再按一次退出程序,按第一次做提示,再按一次,程序退出. float _waitTime = 2f;//前后两次按退出间隔时间 void OnGUI() { ) { GUI.Label( ...

  3. 【UIScrollView】基本方法+基本描述

    scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(, , , )]; scrollView.backgroundColor = [ ...

  4. git@oschina.net源代码管理使用日记

    git的优势: 1 可以创建分支: 2 版本控制是基于每一次提交的,而不需要考虑每次提交了多少个文件. 下载: 下载网址为:http://git-scm.com/download,根据您的操作系统选择 ...

  5. BZOJ 2753 [SCOI2012] 滑雪和时间胶囊 最小生成树

    题目链接: 题目 2753: [SCOI2012]滑雪与时间胶囊 Time Limit: 50 Sec Memory Limit: 128 MB 问题描述 a180285非常喜欢滑雪.他来到一座雪山, ...

  6. win7旗舰版安装office2007后打开文件提示找不到proplusww.msi

    今天第一次打开2007的excel,出现错误如下: 解决办法: 转自:http://blog.163.com/huacai9420@126/blog/static/521585422011911524 ...

  7. 剑指offer--面试题10--相关

    题目一:判断一个整数是不是2的n次幂 实现大概如下: int main() { ; )) == ) //重要!! std::cout<<"YES!"<<st ...

  8. C#动态多线程实例

    在C#中用多线程并不难实现.它有一个命名空间:System.Threading,提供了多线程的支持. 要开启一个新线程,须要以下的初始化: ThreadStart startDownload = ne ...

  9. websphere变成英文了怎么变回中文

    今天进来发现,websphere在浏览器里面居然是英文的.这是因为我的浏览器少了一个中文语言设置,其实和页面编码无关. 解决办法: IE浏览器右键属性 -- internet选项 --  常规 -- ...

  10. HTTP/2 对 Web 性能的影响(上)

    一.前言 HTTP/2 于 2015 年 5 月正式推出.自诞生以来,它就一直在影响着网络性能最佳实践.在本篇文章中,我们将讨论 HTTP/2 的二进制帧.延迟削减.潜在利弊以及相应的应对措施. 超文 ...