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> ...
随机推荐
- linux下编译qt5.6.0静态库——configure配置
linux下编译qt5.6.0静态库 linux下编译qt5.6.0静态库 configure生成makefile 安装选项 Configure选项 第三方库: 附加选项: QNX/Blackberr ...
- PHP输出控制(Output Control)函数
ob_start 此函数将打开输出缓冲.当输出缓冲激活后,脚本将不会输出内容(除http标头外),相反需要输出的内容被存储在内部缓冲区中. 内部缓冲区的内容可以用 ob_get_contents() ...
- Python自动化之socket初识
1. os.popen() os.system(cmd)会直接输出命令的结果到屏幕上,返回一个状态码0或1. os.popen(cmd)会返回一个<open file 'dir', mode ' ...
- 解压.tar.gz出错gzip: stdin: not in gzip format tar: /Child returned status 1 tar: Error is not recoverable: exiting now
先查看文件真正的属性是什么? [root@xxxxx ~]# tar -zxvf tcl8.4.16-src.tar.gz gzip: stdin: not in gzip format tar: ...
- 音频DAC剖析---解开HI-FI音质的秘密
选自:http://mp3.zol.com.cn/54/547689.html 无论我们是买MP3.MP4也好,实际上我们的数码播放器最经常使用的就是音乐播放功能,所以数码播放器的音质,一直是消费者的 ...
- Database、User、Schema、Tables、Col、Row
可以把Database看作是一个大仓库,仓库分了很多很多的房间,Schema就是其中的房间,一个Schema代表一个房间,Table可以看作是每个Schema中的床,Table(床)就被放入每个房间中 ...
- [k]css盒模型
box-sizing : content-box || border-box || inherit 1.content-box:此值为其默认值.元素的宽度/高度(width/height)等于元素边 ...
- document.documentElement.scrollTop || document.body.scrollTop
如果有doctype的声明,需要用document.documentElement.scrollTop没有doctype的声明,用document.body.scrollTop
- Qt 对话框显示控制按钮
在对话框窗体构造函数加入 SystemDialog::SystemDialog(QWidget *parent) : QDialog(parent), ui(new Ui::SystemDialog) ...
- 跟着 8 张思维导图学习 Javascript
学习的道路就是要不断的总结归纳,好记性不如烂笔头,so,下面将po出8张javascript相关的思维导图. 思维导图小tips:思维导图又叫心智图,是表达发射性思维的有效的图形思维工具 ,它简单却又 ...