zoukankan      html  css  js  c++  java
  • hdu3394--Railway(点的双连通分量)

    一个公园中有 n 个景点,景点之间通过无向的道路来连接,如果至少两个环公用一条路,路上的游客就会发生冲突;如果一条路不属于任何的环,这条路就没必要修

    问,有多少路不必修,有多少路会发生冲突

    每一个连通块中,如果边数大于点数,这个块中所有的边全部是冲突边。

    所有桥为不需要修建的路。

    通过这题学习点的双连通分量怎么求。强连通和双连通的题就做到这吧。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int M = 200010;
    const int N = 10010;
    
    struct Edge {
        int from, to;
        int next;
    } edge[M];
    int head[N];
    int cnt_edge;
    void add_edge(int u, int v)
    {
        edge[cnt_edge].from = u;
        edge[cnt_edge].to = v;
        edge[cnt_edge].next = head[u];
        head[u] = cnt_edge++;
    }
    
    int dfn[N]; int idx;
    int low[N];
    stack<Edge> stk;
    set<int> bcc;
    int cut;    // 桥的数量
    int ans;    // 冲突边数量
    int m, n;
    
    void dfs(int u, int pre)
    {
        dfn[u] = low[u] = ++idx;
        for (int i = head[u]; i != -1; i = edge[i].next)
        {
            int v = edge[i].to;
            if (v == pre) continue;
            if (!dfn[v])
            {
                stk.push(edge[i]);
                dfs(v, u);
                low[u] = min(low[u], low[v]);
                if (low[v] >= dfn[u])       // 割点
                {
                    Edge tmp;
                    int cnt = 0;
                    bcc.clear();
                    do {
                        cnt++;
                        tmp = stk.top();
                        stk.pop();
                        bcc.insert(tmp.from);
                        bcc.insert(tmp.to);
                    } while (tmp.from != u || tmp.to != v);
                    if (cnt > bcc.size()) ans += cnt;
                }
                if (low[v] > dfn[u]) ++cut;
            }
            else if (dfn[v] < dfn[u])
            {
                stk.push(edge[i]);
                low[u] = min(low[u], dfn[v]);
            }
        }
    }
    
    void init()
    {
        memset(head, -1, sizeof head);
        memset(dfn, 0, sizeof dfn);
        ans = cut = cnt_edge = idx = 0;
    }
    
    int main()
    {
        while (~scanf("%d%d", &n, &m))
        {
            if (n == 0 && m == 0) break;
            int u, v;
            init();
            for (int i = 0; i < m; ++i)
            {
                scanf("%d%d", &u, &v);
                add_edge(u, v);
                add_edge(v, u);
            }
            for (int i = 1; i <= n; ++i)
            if (!dfn[i]) dfs(i, -1);
            printf("%d %d
    ", cut, ans);
        }
        return 0;
    }
    

      

  • 相关阅读:
    定义一个JobService,开启本地服务和远程服务
    提高Service优先级
    app中使用
    在java中
    每天学习点--------第六天(2017-10-10) 摘要: mysql和Oracle的区别
    每天学习点--------第五天(2017-10-9) 摘要: 常用的集合
    每天学习点--------第三天(2017-09-12)
    每天学习点--------第二天(2017-09-09)
    每天学习点--------第一天(2017-09-08)
    java开源安全框架-------Apache Shiro--第一天
  • 原文地址:https://www.cnblogs.com/wenruo/p/5008312.html
Copyright © 2011-2022 走看看