<题目链接>

题目大意:

给一个无向图,该图只有一个连通分量。然后查询q次,q < 1000, 求每次查询就增加一条边,求剩余桥的个数。

解题分析:

普通的做法就是在每加一条边后,都找一次桥,但是这样肯定超时。

第一种做法是:缩点,因为如果一条边不是桥那么无论怎么加边他肯定都不会变成桥,这样把连通分量缩成一个点。这样全图所有的边就都是桥,这样的话,我们就在加的边里面去找如果加的边是同一个点,那么,肯定不会减少桥,但是如果不是同一个,那么桥肯定减少。

还有一种做法:因为需要u、v之间直接连一条边,所以u->v的原始路径与新连的这条边构成一个环,所以u->v原始路径上的所有桥将不复存在。我们可以先利用Tarjan处理出原图中所有的桥,然后再利用LCA将u->v原始路径的每一条边都求出来(求出u到LCA的所有边和v到LCA的所有边),然后判断该边是否是桥即可,如果是桥,则删除该边的桥标记即可。

下面介绍第二种做法:

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. using namespace std;
  5.  
  6. #define clr(a,b) memset(a,b,sizeof(a))
  7. const int N = 1e5+;
  8. const int M = 4e5+;
  9. int n,m,q,tot,index,bridge;
  10. int dfn[N],low[N],fa[N],dep[N],head[N];
  11. bool cut[N];
  12. struct Edge{
  13. int to,next;
  14. }edge[M];
  15. void init(){
  16. tot=bridge=index=;
  17. clr(head,-);clr(dfn,);clr(dep,);clr(cut,false);
  18. }
  19. void addedge(int u,int v){
  20. edge[tot].to=v,edge[tot].next=head[u];
  21. head[u]=tot++;
  22. }
  23. void tarjan(int u,int pre){
  24. dfn[u]=low[u]=++index;
  25. dep[u]=dep[pre]+; //dep代表该点深度
  26. for(int i=head[u]; i!=-; i=edge[i].next){
  27. int v=edge[i].to;
  28. if(v==pre) continue;
  29. if(!dfn[v]){
  30. fa[v]=u;
  31. tarjan(v,u);
  32. low[u]=min(low[u],low[v]);
  33. if(low[v]>dfn[u]){ //桥的判定定理
  34. cut[v]=; //标记v所在边为桥
  35. bridge++;
  36. }
  37. }
  38. else
  39. low[u]=min(low[u],dfn[v]);
  40. }
  41. }
  42. void LCA(int u,int v){ //利用LCA将u->v原始路径上的所有桥全部删除
  43. if(dep[u]<dep[v]) swap(u,v);
  44. while(dep[u]>dep[v]){ //将u跳到与v深度相同,将路径上碰到的桥全部删除
  45. if(cut[u]){
  46. bridge--;
  47. cut[u]=false;
  48. }
  49. u=fa[u];
  50. }
  51. while(u!=v){ //将u和v同时跳到他们的LCA,在路径中,凡是碰到桥,将该桥删除
  52. if(cut[u]){
  53. bridge--;
  54. cut[u]=false;
  55. }
  56. if(cut[v]){
  57. bridge--;
  58. cut[v]=false;
  59. }
  60. u=fa[u],v=fa[v];
  61. }
  62. }
  63. int main(){
  64. int ncase=;
  65. while(~scanf("%d%d",&n,&m) && (n||m)){
  66. init();
  67. for(int i=; i<=m; i++){
  68. int u,v;scanf("%d%d",&u,&v);
  69. addedge(u,v);addedge(v,u);
  70. }
  71. tarjan(,); //预处理出原图中所有的桥
  72. scanf("%d",&q);
  73. printf("Case %d:\n",++ncase);
  74. while(q--){
  75. int u,v;scanf("%d%d",&u,&v);
  76. LCA(u,v); //u,v之间连一条边,则改变与u->v的原始路径构成环,所以u->v原始路径上的所有桥将不复存在
  77. printf("%d\n",bridge);
  78. }puts("");
  79. }
  80. return ;
  81. }

2018-11-06

poj 3694 Network 【Tarjan】+【LCA】的更多相关文章

  1. 【HDOJ2586】【Tarjan离线求LCA】

    http://acm.hdu.edu.cn/showproblem.php?pid=2586 How far away ? Time Limit: 2000/1000 MS (Java/Others) ...

  2. Poj 3694 Network (连通图缩点+LCA+并查集)

    题目链接: Poj 3694 Network 题目描述: 给出一个无向连通图,加入一系列边指定的后,问还剩下多少个桥? 解题思路: 先求出图的双连通分支,然后缩点重新建图,加入一个指定的边后,求出这条 ...

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

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

  4. POJ 3694 Network (tarjan + LCA)

    题目链接:http://poj.org/problem?id=3694 题意是给你一个无向图n个点,m条边,将m条边连接起来之后形成一个图,有Q个询问,问将u和v连接起来后图中还有多少个桥. 首先用t ...

  5. poj 3694 Network : o(n) tarjan + O(n) lca + O(m) 维护 总复杂度 O(m*q)

    /** problem: http://poj.org/problem?id=3694 问每加一条边后剩下多少桥 因为是无向图,所以使用tarjan缩点后会成一棵树并维护pre数组 在树上连一条边(a ...

  6. POJ 1470 Closest Common Ancestors【近期公共祖先LCA】

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u013912596/article/details/35311489 题目链接:http://poj ...

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

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

  8. poj 3694 Network(割边+lca)

    题目链接:http://poj.org/problem?id=3694 题意:一个无向图中本来有若干条桥,有Q个操作,每次加一条边(u,v),每次操作后输出桥的数目. 分析:通常的做法是:先求出该无向 ...

  9. 【HDOJ4635】【Tarjan缩点+思维】【经典】

    http://acm.hdu.edu.cn/showproblem.php?pid=4635 Strongly connected Time Limit: 2000/1000 MS (Java/Oth ...

随机推荐

  1. centos7搭建smb服务

    1 yum install samba samba-client samba-common -y  安装smb服务 2 cp -a  /etc/samba/smb.conf /etc/samba/sm ...

  2. ios  调整 label 的字体行间距

     UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 100, self.view.frame.size.width, 200) ...

  3. Confluence 6 安装一个语言组件

    Confluence 捆绑了一系列的语言包.这些语言包在 'Language Configuration'  界面中的语言选项中.在 Confluence 的管理员控制台,你可以选择 Choosing ...

  4. Confluence 6 附件存储配置

    在默认的情况下 Confluence 的附件存储在 home 目录中(例如,在文件系统). 希望对 Confluence 的附件存储进行配置: 在屏幕的右上角单击 控制台按钮 ,然后选择 Genera ...

  5. Confluence 6 数据库整合有关你数据库的大小写敏感问题

    'Collation' 是数据如何被存储和比较的规则.大小写是否敏感是有关字符集设置的一个方面.其他大小写敏感的方面有 kana (Japanese script)和宽度(单字节对比双字节长度). 设 ...

  6. flask 初学1

    py 文件中 from flask import Flask,redirect,request,url_for,jsonifyfrom Flask_5.config import Config fro ...

  7. vue-列表嵌套

  8. ionic3 Injectable 引入NavController

    在service里 引入 navcontroller 报错 And I get error No provider for NavController. 一个比较容易解决的方法, import {Io ...

  9. python网络爬虫笔记(四)

    一.python中的高阶函数算法 1.sorted()函数的排序   sorted()函数是一个高阶函数,还可以接受一个key函数来实现自定义的函数排序,key指定的函数作用于每个序列元素上,并根据k ...

  10. cf1110E 思维

    /* Ci'=Ci+1 + Ci-1 -Ci Ci+1 - Ci' = Ci - Ci-1 Ci' - Ci-1 = Ci+1 - Ci; 即求一次Ci’等价于交换Ci和Ci-1 与 Ci+1和Ci的 ...