zoukankan      html  css  js  c++  java
  • poj3177--Redundant Paths(边的双连通)

    有n个牧场,Bessie 要从一个牧场到另一个牧场,要求至少要有2条独立的路可以走。现已有m条路,求至少要新建多少条路,使得任何两个牧场之间至少有两条独立的路。两条独立的路是指:没有公共边的路,但可以经过同一个中间顶点。

    一个连通无向图最少加几条边变成双连通图
    (缩点后叶子节点(即度数为1)的个数 + 1) / 2

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    /*
    一个连通无向图最少加几条边变成双连通图
    边的双连通
    (缩点后叶子节点(即度数为1)的个数 + 1)/2
    */
    
    const int N = 5005;
    const int M = 200005;
    
    struct Edge {
        int to, next;
        bool cut;
    } edge[M];
    int cnt_edge;
    int head[N];
    void add_edge(int u, int v)
    {
        edge[cnt_edge].to = v;
        edge[cnt_edge].next = head[u];
        edge[cnt_edge].cut = false;
        head[u] = cnt_edge++;
    }
    
    int dfn[N]; int idx;
    int low[N];
    int stk[N]; int top;
    int kind[N]; int cnt;
    bool in[N];
    
    int bridge;
    
    int n, m;
    
    void tarjan(int u, int pre)
    {
        low[u] = dfn[u] = ++idx;
        in[u] = true;
        stk[++top] = u;
        for (int i = head[u]; i != -1; i = edge[i].next)
        {
            int v = edge[i].to;
            if (v == pre) continue;
            if (!dfn[v])
            {
                tarjan(v, u);
                low[u] = min(low[u], low[v]);
                if (low[v] > dfn[u])
                {
                    bridge++;
                    edge[i].cut = true;
                    edge[i ^ 1].cut = true;
                }
            }
            else low[u] = min(low[u], dfn[v]);
        }
        if (low[u] == dfn[u])
        {
            cnt++;
            int v;
            do {
                v = stk[top--];
                in[v] = false;
                kind[v] = cnt;
            } while (u != v);
        }
    }
    
    int deg[N];
    void solve()
    {
        for (int u = 1; u <= n; ++u)
        {
            for (int i = head[u]; i != -1; i = edge[i].next)
            {
                if (edge[i].cut) deg[kind[u]]++;
            }
        }
        int leaf = 0;
        for (int i = 1; i <= cnt; ++i)
            if (deg[i] == 1) ++leaf;
        printf("%d
    ", (leaf + 1) / 2);
    }
    
    void init()
    {
        memset(head, -1, sizeof head);
        memset(dfn, 0, sizeof dfn);
        memset(deg, 0, sizeof deg);
    
        top = idx = cnt = cnt_edge = 0;
    }
    
    int main()
    {
        int a, b;
        while (~scanf("%d%d", &n, &m))
        {
            init();
            for (int i = 0; i < m; ++i)
            {
                scanf("%d%d", &a, &b);
                add_edge(a, b);
                add_edge(b, a);
            }
            tarjan(1, -1);
            solve();
        }
        return 0;
    }
    

      

  • 相关阅读:
    Flip Game(枚举)Poj
    Ubuntu下启动Eclipse报错:A Java RunTime Environment (JRE) or Java Development Kit (JDK) must
    [cocos2dx笔记012]一定简易的UI配置类
    [MSSQL]採用pivot函数实现动态行转列
    (八十八)VFL语言初步
    Leetcode 218 The Skyline Problem
    mac 下作流程图工具omnigraffle
    JSP生成word文件
    状态压缩dp poj 3254 hdu5045
    hdu 1215 七夕节
  • 原文地址:https://www.cnblogs.com/wenruo/p/4990779.html
Copyright © 2011-2022 走看看