zoukankan      html  css  js  c++  java
  • POJ 3177

    题目大意:

    给定一个N个点,M条边的无向连通图(可能有重边),要求让任意两点间都有两条或以上的路径,且这些路径没有公共边。问至少需要加多少条边?

    N<=5e3,M<=1e4。

    求双连通分量并缩点。详见:https://www.cnblogs.com/frog112111/p/3367039.html

    注意由于本题数据允许重边(尽管讨论区有人吐槽数据太水),DFS时判断割边的条件应为low[to] > dfn[cur],该边的重数为1。

    实现的时候用了并查集来维护属于同一双联通分量的点,标记割边时将它的重数变成-1。

    代码:(都8102年了贵OJ还不支持C++11-_-||)

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 #include <map>
      5 
      6 using namespace std;
      7 
      8 const int maxN = 5000 + 5;
      9 const int notVisited = -1;
     10 
     11 map<int, int> elist[maxN];
     12 int dfn[maxN];
     13 int low[maxN];
     14 int ufs[maxN];
     15 int cnt[maxN];
     16 int lastDfn = 0;
     17 int N, M;
     18 
     19 inline void addEdge(int u, int v)
     20 {
     21     map<int, int>::iterator it = elist[u].find(v);
     22     if (it != elist[u].end())
     23         it->second += 1;
     24     else
     25         elist[u].insert(make_pair(v, 1));
     26 }
     27 
     28 void input()
     29 {
     30     scanf("%d%d", &N, &M);
     31     for (int u, v, i = 1; i <= M; i++)
     32     {
     33         scanf("%d%d", &u, &v);
     34         addEdge(u, v);
     35         addEdge(v, u);
     36     }
     37 }
     38 
     39 void init()
     40 {
     41     memset(dfn, -1, sizeof(dfn));
     42     memset(low, 0x3f, sizeof(low)); //infinity
     43     lastDfn = 0;
     44     for (int i = 1; i <= N; i++)
     45         ufs[i] = i;
     46 }
     47 
     48 int findUfs(int x)
     49 {
     50     return ufs[x] == x ? x : (ufs[x] = findUfs(ufs[x]));
     51 }
     52 
     53 bool unifyUfs(int x, int y)
     54 {
     55     int fx = findUfs(x);
     56     int fy = findUfs(y);
     57     if (fx == fy)
     58         return false;
     59     ufs[fx] = fy;
     60     return true;
     61 }
     62 
     63 void dfs(int cur, int last)
     64 {
     65     dfn[cur] = low[cur] = (++lastDfn);
     66 
     67     for (map<int, int>::iterator it = elist[cur].begin(); it != elist[cur].end(); ++it)
     68     {
     69         int to = it->first;
     70         if (dfn[to] == notVisited)
     71         {
     72             dfs(to, cur);
     73             if (it->second >= 2 || low[to] <= dfn[cur])
     74                 unifyUfs(cur, to);
     75             else
     76                 it->second = -1;
     77             low[cur] = min(low[cur], low[to]);
     78         }
     79         else if (to != last)
     80         {
     81             unifyUfs(to, cur);
     82             low[cur] = min(low[cur], dfn[to]);
     83         }
     84     }
     85 }
     86 
     87 int solve()
     88 {
     89     init();
     90     dfs(1, 0);
     91 
     92     for (int i = 1; i <= N; i++)
     93         for (map<int, int>::iterator it = elist[i].begin(); it != elist[i].end(); ++it)
     94         {
     95             if (it->second > 0)
     96                 continue;
     97 
     98             int to = it->first;
     99             int fi = findUfs(i);
    100             int ft = findUfs(to);
    101             if (fi != ft)
    102             {
    103                 cnt[fi] += 1;
    104                 cnt[ft] += 1;
    105             }
    106         }
    107 
    108     return ((int)count(cnt + 1, cnt + N + 1, 1) + 1) / 2;
    109 }
    110 
    111 int main()
    112 {
    113     input();
    114     printf("%d", solve());
    115     return 0;
    116 }
  • 相关阅读:
    @Order
    uri和url , 以及末尾加不加 '/'
    windows删除右键新建多余选项
    Typora 指南
    常见状态码/HttpStatusCode
    final 修饰符
    4. shiro-整合redis
    springboot 整合mybatis 一级缓存失效
    springboot查看具体访问的url片段
    JavaSE:NIO
  • 原文地址:https://www.cnblogs.com/Onlynagesha/p/8452656.html
Copyright © 2011-2022 走看看