• Hdu 4612 Warm up (双连通分支+树的直径)


    题目链接:

      Hdu 4612 Warm up

    题目描述:

      给一个无向连通图,问加上一条边后,桥的数目最少会有几个?

    解题思路:

      题目描述很清楚,题目也很裸,就是一眼看穿怎么做的,先求出来双连通分量,然后缩点重新建图,用bfs求树的直径,直径的长度就是减去桥的数目。

    这个题目需要手动扩展,而且手动扩展的话要用C++提交,G++re哭了。

      1 #include <cstdio>
      2 #include <queue>
      3 #include <cstring>
      4 #include <iostream>
      5 #include <algorithm>
      6 #pragma comment(linker, "/STACK:1024000000,1024000000")
      7 using namespace std;
      8 
      9 const int maxn = 200005;
     10 struct node
     11 {
     12     int to, next;
     13 }edge[10*maxn], Edge[2*maxn];
     14 int vis[maxn], dist[maxn];
     15 int head[maxn], low[maxn], dfn[maxn], id[maxn], Head[maxn];
     16 int stack[maxn], tot, Tot, ntime, top, cnt, Max, end_p;
     17 
     18 void init ()
     19 {
     20     tot = ntime = top = Tot = cnt = Max = end_p = 0;
     21     memset (id, 0, sizeof(id));
     22     memset (low, 0, sizeof(low));
     23     memset (dfn, 0, sizeof(dfn));
     24     memset (head, -1, sizeof(head));
     25     memset (stack, 0, sizeof(stack));
     26     memset (Head, -1, sizeof(Head));
     27 }
     28 void Add (int from, int to)
     29 {
     30     Edge[Tot].to = to;
     31     Edge[Tot].next = Head[from];
     32     Head[from] = Tot ++;
     33 }
     34 void add (int from, int to)
     35 {
     36     edge[tot].to = to;
     37     edge[tot].next = head[from];
     38     head[from] = tot ++;
     39 }
     40 void Tarjan (int u, int father)
     41 {
     42     int k = 0;
     43     low[u] = dfn[u] = ++ntime;
     44     stack[top++] = u;
     45     for (int i=head[u]; i!=-1; i=edge[i].next)
     46     {
     47         int v = edge[i].to;
     48         if (v == father && !k)
     49         {
     50             k ++;
     51             continue;
     52         }
     53         if (!dfn[v])
     54         {
     55             Tarjan (v, u);
     56             low[u] = min (low[u], low[v]);
     57         }
     58         else
     59             low[u] = min (low[u], dfn[v]);
     60     }
     61     if (low[u] == dfn[u])
     62     {
     63         cnt ++;
     64         while (1)
     65         {
     66             int v = stack[--top];
     67             id[v] = cnt;
     68             if (v == u)
     69                 break;
     70         }
     71     }
     72 }
     73 void bfs (int s)
     74 {
     75     queue<int>Q;
     76     int u, v;
     77     memset (vis, 0,sizeof(vis));
     78     vis[s] = 1;
     79     dist[s] = 0;
     80     Q.push(s);
     81     while (!Q.empty())
     82     {
     83         u = Q.front();
     84         Q.pop();
     85         for (int i=Head[u]; i!=-1; i=Edge[i].next)
     86         {
     87             v = Edge[i].to;
     88             if (!vis[v])
     89             {
     90                 vis[v] = 1;
     91                 dist[v] = dist[u] + 1;
     92                 Q.push(v);
     93                 if (dist[v] > Max)
     94                 {
     95                     Max = dist[v];
     96                     end_p = v;
     97                 }
     98             }
     99         }
    100     }
    101 }
    102 void solve (int n)
    103 {
    104     int sum = 0;
    105     Tarjan (1, 0);
    106     for (int i=1; i<=n; i++)
    107         for (int j=head[i]; j!=-1; j=edge[j].next)
    108         {
    109             int u = id[i];
    110             int v = id[edge[j].to];
    111             if (v != u)
    112                 {
    113                     Add (u, v);
    114                     sum ++;
    115                 }
    116         }
    117     sum /= 2;
    118     bfs (1);
    119     bfs (end_p);
    120     printf ("%d
    ", sum - Max);
    121 }
    122 int main ()
    123 {
    124     int n, m;
    125     while (scanf ("%d %d", &n, &m), n+m)
    126     {
    127         init ();
    128         while (m --)
    129         {
    130             int u, v;
    131             scanf ("%d %d", &u, &v);
    132             add (u, v);
    133             add (v, u);
    134         }
    135         solve (n);
    136     }
    137     return 0;
    138 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    1
    vim配置
    pyspark
    添加底部小火箭+目录
    00
    博客园代码高亮设置
    01. 枚举类型
    01. 授权问题
    Android Studio打包签名全过程
    linux 阿里云源地址
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4674331.html
Copyright © 2020-2023  润新知