zoukankan      html  css  js  c++  java
  • POJ 3694 Network ——(桥 + LCA)

      题意:给n个点和m条边,再给出q条边,问每次加一条边以后剩下多少桥。

      分析:这题是结合了LCA和dfn的妙用。_dfn数组和dfn的意义不一样,并非访问的时间戳,_dfn表示的是被访问的顺序,而且是多线程访问下的顺序,举个例子,同一个点分岔开来的点,距离这个点相同距离的点,他们的_dfn的值是相同的,而dfn不是,类似于单线程dfs访问的各点的dfn值是不同的。

      具体见代码:  

      1 #include <stdio.h>
      2 #include <algorithm>
      3 #include <string.h>
      4 #include <map>
      5 #include <vector>
      6 #include <queue>
      7 using namespace std;
      8 const int N = 100000 + 5;
      9 
     10 int n,m,tot,head[N],cnt,dfs_clock,dfn[N],_dfn[N],root[N],low[N];
     11 bool bridge[N];
     12 struct edge
     13 {
     14     int nxt,v;
     15 }edges[N<<2];
     16 
     17 void init()
     18 {
     19     tot = 0,dfs_clock = 0,cnt = 0;
     20     memset(head,-1,sizeof(head));
     21     memset(dfn,0,sizeof(dfn));
     22     memset(_dfn,0,sizeof(_dfn));
     23     memset(bridge,false,sizeof(bridge));
     24     for(int i=1;i<=n;i++) root[i] = i;
     25 }
     26 
     27 void addEdge(int u,int v)
     28 {
     29     edges[tot] = (edge){head[u],v};
     30     head[u] = tot ++;
     31     edges[tot] = (edge){head[v],u};
     32     head[v] = tot ++;
     33 }
     34 
     35 void tarjan(int u)
     36 {
     37     dfn[u] = low[u] = ++dfs_clock;
     38     _dfn[u] = _dfn[root[u]] + 1;
     39     for(int i=head[u];i!=-1;i=edges[i].nxt)
     40     {
     41         edge &e = edges[i];
     42         int v = e.v;
     43         if(!dfn[v])
     44         {
     45             root[v] = u;
     46             tarjan(v);
     47             low[u] = min(low[u],low[v]);
     48             if(low[v] > dfn[u])
     49             {
     50                 cnt ++;
     51                 bridge[v] = true;
     52             }
     53         }
     54         else if(dfn[v] < dfn[u] && v!=root[u]) low[u] = min(low[u],dfn[v]);
     55     }
     56 }
     57 
     58 void LCA(int u,int v)
     59 {
     60     while(_dfn[u] > _dfn[v])
     61     {
     62         if(bridge[u])
     63         {
     64             cnt --;
     65             bridge[u]  = false;
     66         }
     67         u = root[u];
     68     }
     69     while(_dfn[u] < _dfn[v])
     70     {
     71         if(bridge[v])
     72         {
     73             cnt --;
     74             bridge[v] = false;
     75         }
     76         v = root[v];
     77     }
     78     while(u != v)
     79     {
     80         if(bridge[u])
     81         {
     82             cnt --;
     83             bridge[u] = false;
     84         }
     85         if(bridge[v])
     86         {
     87             cnt --;
     88             bridge[v] = false;
     89         }
     90         u = root[u];
     91         v = root[v];
     92     }
     93 }
     94 
     95 void solve()
     96 {
     97     for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
     98 
     99     int q;scanf("%d",&q);
    100     while(q--)
    101     {
    102         int u,v;scanf("%d%d",&u,&v);
    103         LCA(u,v);
    104         printf("%d
    ",cnt);
    105     }
    106     puts("");
    107 }
    108 
    109 int main()
    110 {
    111     int kase = 1;
    112     while(scanf("%d%d",&n,&m)==2)
    113     {
    114         if(n==0 && m==0) break;
    115         init();
    116         printf("Case %d:
    ",kase++);
    117         while(m--)
    118         {
    119             int u,v;scanf("%d%d",&u,&v);
    120             addEdge(u,v);
    121         }
    122         solve();
    123     }
    124 }
  • 相关阅读:
    关于Vue的路由、脚手架笔记
    个人Vue-1.0学习笔记
    评论发布信息可插入QQ表情
    21 九宫格布局
    20 随机验证码&发表评论
    19 表单验证&上传图片验证
    18 百度换肤&千千音乐盒
    17 JS-图片切换PLUS&关闭小广告
    16 JS应用-图片切换&衣服相册
    15 JS应用-todolist任务
  • 原文地址:https://www.cnblogs.com/zzyDS/p/5790875.html
Copyright © 2011-2022 走看看