zoukankan      html  css  js  c++  java
  • hdu 2460

    这是一道双联通分量的题,要用到LCA算法;

    听说这个算法有两种实现方式:一个是dfs+线段树或着RMQ;一个是用tarjin;

    我用的是tarjin;

    题目比较简单,就是每次加了一条边之后剩下的桥的个数;

    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<vector>
      5 using namespace std;
      6 #define MAXN 100009
      7 #pragma comment(linker,"/STACk:10240000,10240000")
      8 
      9 int n,m,cnt,NE,BridgeNum;
     10 int parent[MAXN],low[MAXN],dfn[MAXN];
     11 bool mark[MAXN],isbridge[MAXN];
     12 vector<int>ve[MAXN];
     13 
     14 void Tarjan(int u,int father)
     15 {
     16     int flag=0;
     17     low[u]=dfn[u]=++cnt;
     18     mark[u]=true;
     19     int l=ve[u].size();
     20     for(int i=0; i<l; i++)
     21     {
     22         int v=ve[u][i];
     23         if(v==father&&!flag)
     24         {
     25             flag=1;
     26             continue;
     27         }
     28         if(dfn[v]==0)
     29         {
     30             parent[v]=u;
     31             Tarjan(v,u);
     32             low[u]=min(low[u],low[v]);
     33             if(low[v]>dfn[u])
     34             {
     35                 isbridge[v]=1;
     36                 BridgeNum++;
     37             }
     38         }
     39         else if(mark[v])
     40             low[u]=min(low[u],dfn[v]);
     41     }
     42 }
     43 
     44 void LCA(int u,int v)
     45 {
     46     while(dfn[u]>dfn[v])
     47     {
     48         if(isbridge[u])
     49         {
     50             BridgeNum--;
     51             isbridge[u]=0;
     52         }
     53         u=parent[u];
     54     }
     55     while(dfn[v]>dfn[u])
     56     {
     57         if(isbridge[v])
     58         {
     59             BridgeNum--;
     60             isbridge[v]=0;
     61         }
     62         v=parent[v];
     63     }
     64     while(u!=v)
     65     {
     66         if(isbridge[u])
     67         {
     68             BridgeNum--;
     69             isbridge[u]=0;
     70         }
     71         if(isbridge[v])
     72         {
     73             BridgeNum--;
     74             isbridge[v]=0;
     75         }
     76         u=parent[u],v=parent[v];
     77     }
     78 }
     79 int main()
     80 {
     81     int u,v,Q,ca=1;
     82     while(scanf("%d%d",&n,&m)&&(n+m))
     83     {
     84         BridgeNum=NE=cnt=0;
     85         for(int i=0; i<=n; i++)
     86             ve[i].clear();
     87         while(m--)
     88         {
     89             scanf("%d%d",&u,&v);
     90             ve[u].push_back(v);
     91             ve[v].push_back(u);
     92         }
     93         memset(isbridge,0,sizeof isbridge);
     94         memset(dfn,0,sizeof dfn);
     95         memset(mark,0,sizeof mark);
     96         for(int i=1; i<=n+1; i++)parent[i]=i;
     97         Tarjan(1,-1);
     98         printf("Case %d:
    ",ca++);
     99         scanf("%d",&Q);
    100         while(Q--)
    101         {
    102             scanf("%d%d",&u,&v);
    103             LCA(u,v);
    104             printf("%d
    ",BridgeNum);
    105         }
    106         printf("
    ");
    107     }
    108     return 0;
    109 }
    View Code
  • 相关阅读:
    smarty中ifelse、foreach以及获取数组中键值名的一个实例
    smarty逻辑运算符
    python strip()函数 介绍
    (转)论python工厂函数与内建函数
    数据结构哈希表(转)
    哈希表算法的编写
    哈希表(转)
    平衡二叉树的旋转操作
    并查集详解(转)
    Java数组技巧攻略
  • 原文地址:https://www.cnblogs.com/yours1103/p/3302848.html
Copyright © 2011-2022 走看看