zoukankan      html  css  js  c++  java
  • poj3694(lca + tarjan求桥模板)

    题目链接: http://poj.org/problem?id=3694

    题意: 给出一个 n 个节点 m 条边的图, 然后有 q 组形如 x, y 的询问, 在前面的基础上连接边 x, y, 输出当前图中有多少桥 .

    思路: http://www.cnblogs.com/scau20110726/archive/2013/05/29/3106073.html

    代码:

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 using namespace std;
     5 
     6 const int MAXN = 1e5 + 10;
     7 
     8 struct node{
     9     int v, next, use;
    10 }edge[MAXN << 2];
    11 
    12 bool bridge[MAXN];
    13 int low[MAXN], dfn[MAXN], vis[MAXN];
    14 int head[MAXN], pre[MAXN], ip, sol, count;
    15 
    16 void init(void){
    17     memset(head, -1, sizeof(head));
    18     memset(vis, false, sizeof(vis));
    19     memset(bridge, false, sizeof(bridge));
    20     count = sol = ip = 0;
    21 }
    22 
    23 void addedge(int u, int v){
    24     edge[ip].v = v;
    25     edge[ip].use = 0;
    26     edge[ip].next = head[u];
    27     head[u] = ip++;
    28 }
    29 
    30 void tarjan(int u){
    31     vis[u] = 1;
    32     dfn[u] = low[u] = count++;
    33     for(int i = head[u]; i != -1; i = edge[i].next){
    34         if(!edge[i].use){
    35             edge[i].use = edge[i ^ 1].use = 1;
    36             int v = edge[i].v;
    37             if(!vis[v]){
    38                 pre[v] = u;
    39                 tarjan(v);
    40                 low[u] = min(low[u], low[v]);
    41                 if(dfn[u] < low[v]){
    42                     sol++;
    43                     bridge[v] = true;
    44                 }
    45             }else if(vis[v] == 1){
    46                 low[u] = min(low[u], dfn[v]);
    47             }
    48         }
    49     }
    50     vis[u] = 2;
    51 }
    52 
    53 void LCA(int u, int v){
    54     if(dfn[u] > dfn[v]) swap(u, v);
    55     while(dfn[v] > dfn[u]){//判断一下u,v是否在同一条树枝上
    56         if(bridge[v]) sol--;
    57         bridge[v] = false;
    58         v = pre[v];
    59     }
    60     while(u != v){//找lca
    61         if(bridge[u]) sol--;
    62         if(bridge[v]) sol--;
    63         bridge[u] = bridge[v] = false;
    64         u = pre[u];
    65         v = pre[v];
    66     }
    67 }
    68 
    69 int main(void){
    70     int n, m, q, x, y, cas = 1;
    71     while(~scanf("%d%d", &n, &m)){
    72         if(!n && !m) break;
    73         init();
    74         for(int i = 0; i < m; i++){
    75             scanf("%d%d", &x, &y);
    76             addedge(x, y);
    77             addedge(y, x);
    78         }
    79         pre[1] = 1;
    80         tarjan(1);
    81         printf("Case %d:
    ", cas++);
    82         scanf("%d", &q);
    83         while(q--){
    84             scanf("%d%d", &x, &y);
    85             LCA(x, y);
    86             printf("%d
    ", sol);
    87         }
    88         puts("");
    89     }
    90     return 0;
    91 }
    View Code
  • 相关阅读:
    SpringMVC什么时候配置 视图解析器
    打印数组的5种方式
    集合区别(list和linkedlist的区别)?
    回归测试
    dom4j组装xml 以及解析xml
    java操作文件创建、删除
    powerdesigner里的table背景色是不是可以修改的?
    如何设定editplus为txt默认打开程序?
    PowerDesigner怎样才能在修改表的字段Name的时候Code不自动跟着变
    PowerDesigner怎么调出工具箱?
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/7274908.html
Copyright © 2011-2022 走看看