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> ...
随机推荐
- Python super继承详解
MRO(Method resolution order)是python用来解析方法调用顺序的,mro中记录了一个类的所有基类的类类型序列,super不是简单地调用基类的方法,而是按照MRO中的顺序来调 ...
- 2016全国研究生数学建模A题多无人机协同任务规划——基于分布式协同多旅行商MTSP遗传算法
MTSP问题是指:有Ⅳ个城市,要求旅行商到达每个城市各一次,且仅一次,并[旦 1到起点,且要求旅行路线最短.而多旅行商问题M个旅行商从同一个城市(或多个城市)出发.分羽走一条旅路线,且总路程缀短.有关 ...
- 第七天 面向对象进阶与socket编程
1.静态方法(用得少)(解除某个函数跟类的关联,加了静态方法后,类便不能将类的参数传给静态方法函数了) class Dog(object): def __init__(self,name): @sta ...
- cpu和io进程调度时间
[题目] 在一个单CPU的计算机系统中,有两台外部设备R1.R2和三个进程P1.P2.P3.系统采用可剥夺式优先级的进程调度方案,且所有进程可以并行使用I/O设备,三个进程的优先级.使用设备的先后顺序 ...
- 【转】.so兼容32位和64位
本文转自:http://blog.csdn.net/fwt336/article/details/51700300 安卓的兼容性是一个很令人头疼的问题,这几天又遇到了,还好还是解决了. 我遇到的问题是 ...
- ACM/ICPC 之 DP进阶(51Nod-1371(填数字))
原题链接:填数字 顺便推荐一下,偶然看到这个OJ,发现社区运营做得很赞,而且交互和编译环境都很赞(可以编译包括Python,Ruby,Js在内的脚本语言,也可以编译新标准的C/C++11,甚至包括Go ...
- Effective C++ -----条款04:确定对象被使用前已被初始化
为内置型对象进行手工初始化,因为C++不保证初始化它们. 构造函数最好使用成员初值列,而不要在构造函数本体内使用赋值操作.初值列列出的成员变量,其排列次序应该和它们在class中的声明次序相同. 为免 ...
- 后台弹出JS类
using System; using System.Collections.Generic; using System.Text; using System.Web; using System.We ...
- asp.net Excel数据导入到数据库中
protected void Btn_Import_Click(object sender, EventArgs e) { bool Result_Import = false; bool Resul ...
- September 10th 2016 Week 37th Saturday
An innovation that goes beyond imagination again raised the standard. 颠覆想象的创新,再一次刷新标准. An advertisem ...