题目链接:

  Poj 3694 Network

题目描述:

  给出一个无向连通图,加入一系列边指定的后,问还剩下多少个桥?

解题思路:

  先求出图的双连通分支,然后缩点重新建图,加入一个指定的边后,求出这条边两个端点根节点的LCA,统计其中的桥,然后把这个环中的节点加到一个集合中,根节点标记为LCA。

题目不难,坑在了数组初始化和大小

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; const int maxn = ;
struct node
{
int to, next;
} edge[*maxn], Edge[*maxn];
int head[maxn], low[maxn], dfn[maxn], id[maxn], Head[maxn], Father[maxn];
int pre[maxn], deep[maxn], stack[maxn], tot, ntime, top, cnt, Tot; void init ()
{
Tot = tot = ntime = top = cnt = ;
memset (id, , sizeof(id));
memset (low, , sizeof(low));
memset (dfn, , sizeof(dfn));
memset (pre, , sizeof(pre));
memset (head, -, sizeof(head));
memset (deep, , sizeof(deep));
memset (Head, -, sizeof(Head));
}
void Add (int from, int to)
{
Edge[Tot].to = to;
Edge[Tot].next = Head[from];
Head[from] = Tot++;
}
void add (int from, int to)
{
edge[tot].to = to;
edge[tot].next = head[from];
head[from] = tot++;
}
int find (int x)
{
if (x != Father[x])
Father[x] = find(Father[x]);
return Father[x];
}
void dfs (int u, int father, int d)
{
pre[u] = father;
deep[u] = d;
for (int i=Head[u]; i!=-; i=Edge[i].next)
{
int v = Edge[i].to;
if (father != v)
dfs (v, u, d+);
}
}
int LCA (int a, int b)
{
while (a != b)
{
if (deep[a] > deep[b])
a = pre[a];
else if (deep[a] < deep[b])
b = pre[b];
else
{
a = pre[a];
b = pre[b];
}
a = find (a);
b = find (b);
}
return a;
}
void Tarjan (int u, int father)
{
int k = ;
low[u] = dfn[u] = ++ ntime;
stack[top ++] = u;
for (int i=head[u]; i!=-; i=edge[i].next)
{
int v = edge[i].to;
if (father == v && !k)
{
k ++;
continue;
}
if (!dfn[v])
{
Tarjan (v, u);
low[u] = min (low[u], low[v]);
}
else
low[u] = min (low[u], dfn[v]);
}
if (low[u] == dfn[u])
{
cnt ++;
while ()
{
int v = stack[--top];
id[v] = cnt;
if (v == u)
break;
}
}
}
void solve (int n)
{
Tarjan (, );
for (int i=; i<=n; i++)
for (int j=head[i]; j!=-; j=edge[j].next)
{
int u = id[i];
int v = id[edge[j].to];
if (u != v)
Add (u, v);
}
dfs (, , ); for (int i=; i<=cnt; i++)
Father[i] = i;
int q;
cnt --;
scanf ("%d", &q);
while (q --)
{
int u, v;
scanf ("%d %d", &u, &v);
u = find(id[u]);
v = find(id[v]);
int lca = LCA(u, v);
while (u != lca)
{
cnt --;
Father[u] = lca;
u = find (pre[u]);
}
while (v !=lca)
{
cnt --;
Father[v] = lca;
v = find (pre[v]);
}
printf ("%d\n", cnt);
}
}
int main ()
{
int n, m, l = ;
while (scanf ("%d %d",&n, &m), n + m)
{
init ();
while (m --)
{
int u, v;
scanf ("%d %d", &u, &v);
add (u, v);
add (v, u);
}
printf ("Case %d:\n", ++l);
solve (n);
printf ("\n");
}
return ;
}

Poj 3694 Network (连通图缩点+LCA+并查集)的更多相关文章

  1. poj 3694 Network 边双连通+LCA

    题目链接:http://poj.org/problem?id=3694 题意:n个点,m条边,给你一个连通图,然后有Q次操作,每次加入一条边(A,B),加入边后,问当前还有多少桥,输出桥的个数. 解题 ...

  2. POJ 3694 (tarjan缩点+LCA+并查集)

    好久没写过这么长的代码了,题解东哥讲了那么多,并查集优化还是很厉害的,赶快做做前几天碰到的相似的题. #include <iostream> #include <algorithm& ...

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

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

  4. POJ3694 Network 边双缩点+LCA+并查集

    辣鸡错误:把dfs和ldfs搞混...QAQ 题意:给定一个无向图,然后查询q次,求每次查询就在图上增加一条边,求剩余割边的个数. 先把边双缩点,然后预处理出LCA的倍增数组: 然后加边时,从u往上跳 ...

  5. POJ 3694Network(Tarjan边双联通分量 + 缩点 + LCA并查集维护)

    [题意]: 有N个结点M条边的图,有Q次操作,每次操作在点x, y之间加一条边,加完E(x, y)后还有几个桥(割边),每次操作会累积,影响下一次操作. [思路]: 先用Tarjan求出一开始总的桥的 ...

  6. poj 3694双联通缩点+LCA

    题意:给你一个无向连通图,每次加一条边后,问图中桥的数目. 思路:先将图进行双联通缩点,则缩点后图的边就是桥,然后dfs记录节点深度,给出(u,v)使其节点深度先降到同一等级,然后同时降等级直到汇合到 ...

  7. POJ 3694 Network(Tarjan求割边+LCA)

    Network Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 10969   Accepted: 4096 Descript ...

  8. POJ 3694 Network 无向图双联通+LCA

    一开始题目没看清楚,以为是增加那条边后还有多少桥,所以就当做是无向图tarjan缩点后建树,然后求u,v的最近公共祖先,一直wa. 后来再看题目后才发现边放上去后不会拿下来了,即增加i条边后桥的数量. ...

  9. 【CodeForces】827 D. Best Edge Weight 最小生成树+倍增LCA+并查集

    [题目]D. Best Edge Weight [题意]给定n个点m条边的带边权无向连通图,对每条边求最大边权,满足其他边权不变的前提下图的任意最小生成树都经过它.n,m<=2*10^5,1&l ...

随机推荐

  1. CentOS虚拟机与本机同步时间

    接着之前的任务,还是为了在VMWare上搭建分布式hadoop集群.搭着搭着注意到虚拟机上的时间和本机是不同步的,而且可以说是乱七八糟,3台虚拟机时间都与本机差了8个小时以上.首先确认不是时区的问题, ...

  2. 洛谷 U41572 Portal2

    U41572 Portal2 题目背景 某地ENLIGHTENED的XM研究所正在研究Portal的处理法则,想要揭示XM能量的来源以及应用XM能量.ENLIGHTENED的首席科学家Jacks发现其 ...

  3. Orcle定时生成表数据作业

    --建表 create table table41( id ) not null, --主键 col1 ), col2 ), col3 ), col4 int, col5 timestamp, col ...

  4. 【Linux多线程】同步与互斥的区别

    同步与互斥这两个概念经常被混淆,所以在这里说一下它们的区别. 一.同步与互斥的区别 1. 同步 同步,又称直接制约关系,是指多个线程(或进程)为了合作完成任务,必须严格按照规定的 某种先后次序来运行. ...

  5. socket简单理解

    要想理解socket首先得熟悉一下TCP/IP协议族, TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,定义了主 ...

  6. xib或者storyboard设置颜色偏问题(与代码设置颜色不一致)

    选中xib中的label,在右边栏的第三个标签页中第三项是User Defined Runtime Attributes 添加一个keyPath,keyPath值为layer.borderWidth, ...

  7. 使用Node搭建reactSSR服务端渲染架构

    如题:本文所讲架构主要用到技术栈有:Node, Express, React, Mobx, webpack4, ES6, ES7, axios, ejs,  log4js, scss,echarts, ...

  8. C# 最基本的涉及模式(单例模式) C#种死锁:事务(进程 ID 112)与另一个进程被死锁在 锁 | 通信缓冲区 资源上,并且已被选作死锁牺牲品。请重新运行该事务,解决方案: C#关闭应用程序时如何关闭子线程 C#中 ThreadStart和ParameterizedThreadStart区别

    C# 最基本的涉及模式(单例模式) //密封,保证不能继承 public sealed class Xiaohouye    { //私有的构造函数,保证外部不能实例化        private  ...

  9. poj 3233(矩阵高速幂)

    题目链接:http://poj.org/problem?id=3233. 题意:给出一个公式求这个式子模m的解: 分析:本题就是给的矩阵,所以非常显然是矩阵高速幂,但有一点.本题k的值非常大.所以要用 ...

  10. docker init 起步

    #yum install wget http://fedora.mirror.nexicom.net/epel/6/x86_64/epel-release-6-8.noarch.rpm yum -y ...