zoukankan      html  css  js  c++  java
  • POJ 3352 【边双连通分量】.cpp 加多少条边可以使无向图变成双连通分量

    题意:

      某个公园要修路..这将导致两个景点无法连通 

      输入:

      给出n m 表示有n个景点 m条路

      接下来m行每行有a b 表示a景点和b景点相连..

      问加几条边可以使任意两个景点都相连..

    思路:

      先用tarjan算法求出每个连通分量

      然后对无向图来说..变成双连通分量的方法就是(入度为1的点+1)/ 2

    Tips:

      无视POJ的simple输入输出 都是坑人的..T0T

      还有就是现在这样tarjan算法第一次调用的时候就是tarjan(1, 1)

    Code:

      

    View Code
     1 #include <stdio.h>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 #define clr(x) memset(x, 0, sizeof(x))
     6 const int INF = 0x1f1f1f1f;
     7 const int MAXN = 1010;
     8 
     9 struct Edge
    10 {
    11     int to;
    12     int next;
    13 }edge[1000010];
    14 int head[MAXN];
    15 int tot;
    16 
    17 void add(int s, int u)
    18 {
    19     edge[tot].to = u;
    20     edge[tot].next = head[s];
    21     head[s] = tot++;
    22 
    23     edge[tot].to = s;
    24     edge[tot].next = head[u];
    25     head[u] = tot++;
    26 }
    27 
    28 int low[MAXN], dfn[MAXN];
    29 int col[MAXN];
    30 int ti;
    31 
    32 void tarjan(int u, int v)
    33 {
    34     int i, j, k;
    35     low[v] = dfn[v] = ++ti;
    36     for(i = head[v]; i != -1; i = edge[i].next) {
    37         k = edge[i].to;
    38         if(k == u) continue;
    39         if(!dfn[k])
    40             tarjan(v, k);
    41         low[v] = min(low[v], low[k]);
    42     }
    43 }
    44 
    45 int n;
    46 int deg[MAXN];
    47 int ans;
    48 void solve()
    49 {
    50     int i, j, k;
    51     clr(deg);
    52     clr(dfn);
    53     ans = 0, ti = 0;
    54     tarjan(1, 1);
    55     for(i = 1; i <= n; ++i) {
    56         for(j = head[i]; j != -1; j = edge[j].next) {
    57             k = edge[j].to;
    58             if(low[i] != low[k]) deg[low[i]]++;
    59         }
    60     }
    61 
    62     for(i = 1; i <= n; ++i)
    63         if(deg[i] == 1) ans++;
    64 
    65     ans = (ans+1)/2;
    66 }
    67 
    68 int main()
    69 {
    70     int i, j, k;
    71     char sip[20];
    72     int m, a, b;
    73     while(scanf("%d %d", &n, &m) != EOF)
    74     {
    75         tot = 0;
    76         memset(head, 0xff, sizeof(head));
    77 
    78         while(m--) {
    79             scanf("%d %d", &a, &b);
    80             add(a, b);
    81         }
    82 
    83         solve();
    84 
    85         printf("%d\n", ans);
    86     }
    87     return 0;
    88 }

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

  • 相关阅读:
    HCNA Routing&Switching之OSPF度量值和基础配置命令总结
    HCNA Routing&Switching之动态路由协议OSPF DR和BDR
    HCNA Routing&Switching之动态路由协议OSPF建立邻居的条件
    HCNA Routing&Switching之动态路由协议OSPF基础(二)
    HCNA Routing&Switching之动态路由协议OSPF基础(一)
    HCNA Routing&Switching之RIP防环机制
    HCNA Routing&Switching之动态路由协议RIP
    HCNA Routing&Switching之动态路由基本概念
    Serilog 最佳实践
    如何掌握C#的核心技术
  • 原文地址:https://www.cnblogs.com/Griselda/p/2712107.html
Copyright © 2011-2022 走看看