POJ3694 Network(Tarjan双联通分图 LCA 桥)
链接:http://poj.org/problem?id=3694
题意:给定一个有向连通图,每次增加一条边,求剩下的桥的数量。
思路:
给定一个无向连通图,添加一条u->v的边,求此边对图剩余的桥的数量的影响:
若u,v在同一个边双联通分量中,则是否添加无影响。否则从u,v的LCA到u,v的边上所有的桥都不再是桥。
在Tarjan算法中,对在同一个边双联通分量中的点使用并查集合并,实现缩点,同时记录父亲节点。若u,v属于不同的边双连通分量,将dfn较大的点(设为v)向上合并直到dfn[v] < dfn[u],再将u向上合并直到u = v。合并过程中,若发现桥则剩余桥的数量减1。
合并采用并查集,要在合并过程中对路径进行优化,否则超时。
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<vector>
#include<algorithm>
const int INF = 0x3F3F3F3F;
using namespace std;
typedef long long LL; const int N=,M=;
int head[N],tot,n,m,dfn[N],deep;
int bridge;
int fa[N], cnt[N], pre[N];
struct Node{
int to,next;
}e[M];
void init(){
memset(head, -, sizeof(head));
tot = ;
bridge = ;
for(int i = ; i <= n; i++){
fa[i] = i;
cnt[i] = ;
}
} int Find(int x){
while(x != fa[x]){
x = fa[x];
}
return x;
}
bool Union(int x, int y){
int fx = Find(x);
int fy = Find(y);
if(fx!=fy){
if(cnt[fx]>cnt[fy]){
fa[fy]=fx;
cnt[fx]+=cnt[fy];
}else{
fa[fx]=fy;
cnt[fy]+=cnt[fx];
}
return true;
}else{
return false;
}
}
inline void add(int u, int to){
e[tot].to=to;
e[tot].next=head[u];
head[u]=tot++;
}
int dfs(int u, int fa){
int lowu = dfn[u] = ++deep;//lowu为u及其后代所能到达的最远祖先
for(int i=head[u];~i;i=e[i].next){
int v = e[i].to;
if(!dfn[v]){//树叶边,u到v且v未被访问
pre[v] = u;
int lowv = dfs(v, u);
lowu = min(lowu, lowv);
if(lowv > dfn[u]){
bridge++;
}else{
Union(u, v);
}
}else if(dfn[v] < dfn[u] && v != fa){
lowu = min(lowu, dfn[v]);//后向边
}
}
return lowu;
} void tarjan(){
memset(dfn, , sizeof(dfn));
deep=;
for(int i=;i<=n;i++){
if(!dfn[i]){
pre[i] = i;
dfs(i,-);
}
}
} int LCA(int u, int v){
if(Find(u) == Find(v)){
return bridge;
}
if(dfn[u] > dfn[v]){
swap(u, v);
}
while(dfn[u] < dfn[v]){
if(Union(v, pre[v])){
bridge--;
}
v = pre[v];
}
while(u != v){
if(Union(u, pre[u])){
bridge--;
}
u = pre[u];
}
return bridge;
} int main(){
int t = ;
while(~scanf("%d %d", &n, &m) && (n || m)){
init();
int a, b, q;
while(m--){
scanf("%d %d", &a, &b);
add(a, b);
add(b, a);
}
tarjan();
scanf("%d", &q);
printf("Case %d:\n",++t);
while(q--){
scanf("%d %d", &a, &b);
printf("%d\n", LCA(a, b));
}
printf("\n");
}
return ;
}
POJ3694 Network(Tarjan双联通分图 LCA 桥)的更多相关文章
- POJ3694 Network - Tarjan + 并查集
Description 给定$N$个点和 $M$条边的无向联通图, 有$Q$ 次操作, 连接两个点的边, 问每次操作后的图中有几个桥 Solution 首先Tarjan找出边双联通分量, 每个双联通分 ...
- POJ3694 Network 边双缩点+LCA+并查集
辣鸡错误:把dfs和ldfs搞混...QAQ 题意:给定一个无向图,然后查询q次,求每次查询就在图上增加一条边,求剩余割边的个数. 先把边双缩点,然后预处理出LCA的倍增数组: 然后加边时,从u往上跳 ...
- [POJ3694]Network(Tarjan,LCA)
[POJ3694]Network Description A network administrator manages a large network. The network consists o ...
- Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载)
Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载) 转载自:http://hi.baidu.com/lydrainbowcat/blog/item/2 ...
- poj 3417 Network(tarjan lca)
poj 3417 Network(tarjan lca) 先给出一棵无根树,然后下面再给出m条边,把这m条边连上,然后每次你能毁掉两条边,规定一条是树边,一条是新边,问有多少种方案能使树断裂. 我们设 ...
- [Codeforces 555E]Case of Computer Network(Tarjan求边-双连通分量+树上差分)
[Codeforces 555E]Case of Computer Network(Tarjan求边-双连通分量+树上差分) 题面 给出一个无向图,以及q条有向路径.问是否存在一种给边定向的方案,使得 ...
- 网站加载有商务通、商桥,定义js函数触发快商通代码
有的网站已经加载了商务通.商桥的,前期定义了js函数 触发商务通.商桥代码的,可以重新定义新的函数对之前的函数进行覆盖,其 js代码为: var domain = document.domain; / ...
- Tarjan无向图的割点和桥(割边)全网详解&算法笔记&通俗易懂
更好的阅读体验&惊喜&原文链接 感谢@yxc的腿部挂件 大佬,指出本文不够严谨的地方,万分感谢! Tarjan无向图的割点和桥(割边) 导言 在掌握这个算法前,咱们有几个先决条件. [ ...
- tarjan算法求无向图的桥、边双连通分量并缩点
// tarjan算法求无向图的桥.边双连通分量并缩点 #include<iostream> #include<cstdio> #include<cstring> ...
随机推荐
- __getattr__ 与动态属性
直接上代码 >>> class Test(object): ... def __getattr__(self,attr_name): ... setattr(self, attr_n ...
- 音频DAC剖析---解开HI-FI音质的秘密
选自:http://mp3.zol.com.cn/54/547689.html 无论我们是买MP3.MP4也好,实际上我们的数码播放器最经常使用的就是音乐播放功能,所以数码播放器的音质,一直是消费者的 ...
- 网页百度地图API相关资料
百度地图API——网页URI接口.手机网页点击直接导航:js生成一个地图网页 或 直接跳转到百度导航界面 http://developer.baidu.com/map/index.php?title= ...
- 流程图制作在云上 https://www.processon.com/
流程图制作在云上 : https://www.processon.com/
- git diff获取差异文件中文乱码的解决办法
通过git的diff命令对两个commit id的版本进行差异化的对比.中文文件时出现乱码. git diff 6bded8d0c1fe1746c122121217dc0c88667091089 a9 ...
- Nginx如何设置拒绝或允许指定ip访问
location ~ /druid/ { #deny 192.168.1.1; allow 192.168.1.1; deny all; proxy_pass http://127.0.0.1:808 ...
- ios block 导致的循环引用
[[NSNotificationCenter defaultCenter] addObserverForName:@"UIWindowDidRotateNotification" ...
- percona-toolkit 之 【pt-summary】、【pt-mysql-summary】、【pt-config-diff】、【pt-variable-advisor】说明
摘要: 通过下面的这些命令在接触到新的数据库服务器的时候能更好更快的了解服务器和数据库的状况. 1:pt-summary:查看系统摘要报告 执行: pt-summary 打印出来的信息包括:CPU.内 ...
- 2014 12th GDCPC 总结
这次真的需要好好总结反思.... 5月11日,今天是省赛...开赛前,有个人用麦说“balabala”之类的,终于有用麦讲话了=.=像点样了... 跟昨天热身赛一样,我来开VS,建项目云云... 开赛 ...
- Mysql 练习 总结
insert into Course values ('); #---------------Teacher--添加信息---- insert into Teacher values (','李成', ...