• Network(Tarjan+LCA)


    元宵节+情人节晚上刷的题,纪念一下。。
    题意:给出n个点,m条边,然后Q个询问,每次询问输入一条边,输出加入此边后桥的个数。。
      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <queue>
      4 #include <algorithm>
      5 #include <stack>
      6 const int N=205000;
      7 using namespace std;
      8 struct node
      9 {
     10     int u,v,w;
     11     int next;
     12 } edge[N*2];
     13                               //dfn[i]表示点i的深度优先数;
     14 int dfn[N],low[N],head[N];    //low[i]表示点i可到达的最低深度优先数
     15 int vis[N],bridge[N],f[N];
     16 int n,m,cnt,dfs_clock,Conn_cnt;
     17 int ans ;
     18 stack<int>S;
     19 
     20 void init()
     21 {
     22     ans = 0;
     23     cnt = 0;
     24     dfs_clock = 0;
     25     Conn_cnt = 0;
     26     for (int i = 0; i <= n; i++)
     27         f[i] = i;
     28     memset(dfn,0,sizeof(dfn));
     29     memset(low,0,sizeof(low));
     30     memset(vis,0,sizeof(vis));
     31     memset(head,-1,sizeof(head));
     32 }
     33 void add(int u,int v)
     34 {
     35     edge[cnt].v = v;
     36     edge[cnt].next = head[u];
     37     head[u] = cnt++;
     38     edge[cnt].v = u;
     39     edge[cnt].next = head[v];
     40     head[v] =cnt++;
     41 }
     42 
     43 void dfs(int u)//Tarjan算法
     44 {
     45     vis[u] = 1;
     46     dfn[u]=low[u]=++dfs_clock;//设定初值
     47     S.push(u);//将节点u压入栈中
     48     for (int i = head[u]; i!=-1; i=edge[i].next)//遍历u的临接点
     49     {
     50         int v = edge[i].v;
     51         if (!vis[v])//如果改点的深度优先数为0(即没有搜索过)
     52         {
     53             f[v] = u;//记录父节点
     54             dfs(v);//继续向下找
     55             low[u] = min(low[u],low[v]);//回溯过程中计算low[]的值
     56             if(low[v] > dfn[u])
     57             {
     58                 ans++;
     59                 bridge[v] = 1;//标记点u->v为桥
     60             }
     61         }
     62         else if(vis[v]==1&&v!=f[u])
     63         {
     64             low[u] = min(low[u],dfn[v]);
     65         }
     66     }
     67     vis[u] = 2;
     68 }
     69 void LCA(int u,int v)
     70 {
     71     if (dfn[u] < dfn[v])
     72         swap(u,v);
     73     while(dfn[u] > dfn[v])
     74     {
     75         if (bridge[u])
     76         {
     77             ans--;
     78             bridge[u] = 0;
     79         }
     80         u = f[u];
     81     }
     82     while(u!=v)
     83     {
     84         if (bridge[u])
     85         {
     86             ans--;
     87             bridge[u] = 0;
     88         }
     89         if (bridge[v])
     90         {
     91             ans--;
     92             bridge[v] = 0;
     93         }
     94         u = f[u];
     95         v = f[v];
     96     }
     97 }
     98 int main()
     99 {
    100     int u,v,o = 0;
    101     while(~scanf("%d%d",&n,&m))
    102     {
    103         if (n==0&&m==0)
    104             break;
    105         init();
    106         o++;
    107         for (int i = 0; i < m; i++)
    108         {
    109             scanf("%d%d",&u,&v);
    110             add(u,v);
    111         }
    112         dfs(1);
    113         int t;
    114         scanf("%d",&t);
    115         printf("Case %d:
    ",o);
    116         while(t--)
    117         {
    118             scanf("%d%d",&u,&v);
    119             LCA(u,v);
    120             printf("%d
    ",ans);
    121         }
    122         puts("");
    123     }
    124     return 0;
    125 }
    View Code
     
  • 相关阅读:
    矩阵
    手机APP和WAP版的区别
    学习的方法
    ASP.Net中jQuery控制div弹出框效果
    SQL SERVER字符串前加N转换为Unicode编码
    塞尔维亚国家简称编码
    VS2019项目模板中没有[ASP.NET空网站]的解决方案
    Scopus论文数据爬虫
    采集科研文献和数据,我告诉你一个能自动采集的黑科技
    CiteSpace入门教程
  • 原文地址:https://www.cnblogs.com/lahblogs/p/3550132.html
Copyright © 2020-2023  润新知