• Warm up HDU


    求在图中新建一条边后  剩下的最少的桥的数量。。
    先tarjan求桥的数量。。然后缩点。。以连通分量为点建图  bfs求直径

    最后用桥的数量减去直径即为答案

    bfs求直径

    https://www.cnblogs.com/WTSRUVF/p/9307517.html

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <algorithm>
    #include <vector>
    #include <stack>
    #define mem(a, b) memset(a, b, sizeof(a))
    using namespace std;
    const int maxn = 200010, INF = 0x7fffffff;
    int pre[maxn], low[maxn], sccno[maxn], d[maxn], head[maxn], vis[maxn*10];
    int dfs_clock, n, m, scc_cnt, bridge, maxway, pos;
    stack<int> S;
    int cnt1, cnt2;
    struct edge
    {
        int u, v, next;
    }Edge1[maxn*10],Edge2[maxn*10];
    
    void add1(int u, int v)
    {
        Edge1[cnt1].u = u;
        Edge1[cnt1].v = v;
        Edge1[cnt1].next = head[u];
        head[u] = cnt1++;
    
    }
    void add2(int u, int v)
    {
        Edge2[cnt2].u = u;
        Edge2[cnt2].v = v;
        Edge2[cnt2].next = head[u];
        head[u] = cnt2++;
    }
    
    
    void init()
    {
        dfs_clock = 0;
        scc_cnt = 0;
        cnt1 = cnt2 = 0;
        bridge = 0;
        mem(pre, 0);
        mem(vis, 0);
        mem(low, 0);
        mem(head, -1);
        mem(sccno, 0);
    }
    
    void tarjan(int u)
    {
        pre[u] = low[u] = ++dfs_clock;
        S.push(u);
        for(int i=head[u]; i != -1; i=Edge1[i].next)
        {
            int v = Edge1[i].v;
            if(vis[i]) continue;
            vis[i] = vis[i^1] = 1;  //  标记同向边和反向边
            if(!pre[v])
            {
                tarjan(v);
                low[u] = min(low[v], low[u]);
            }
            else if(!sccno[v])
                low[u] = min(low[u], pre[v]);
        }
        if(low[u] == pre[u])
        {
            scc_cnt++;
            for(;;)
            {
                int x = S.top(); S.pop();
                sccno[x] = scc_cnt;
                if(x == u) break;
            }
        }
    }
    
    void bfs(int u)
    {
        queue<int> Q;
        mem(d, 0);
        mem(vis, 0);
        Q.push(u);
        d[u] = 0;
        vis[u] = 1;
        maxway = 0, pos = u;
        while(!Q.empty())
        {
            u = Q.front(); Q.pop();
            for(int i=head[u]; i != -1; i=Edge2[i].next)
            {
                int v = Edge2[i].v;
                if(vis[v]) continue;
                vis[v] = 1;
                d[v] = d[u] + 1;
                if(d[v] > maxway)
                    maxway = d[v], pos = v;
                Q.push(v);
            }
        }
    }
    
    int main()
    {
        while(~scanf("%d%d",&n, &m) && n+m)
        {
            init();
            for(int i=0; i<m; i++)
            {
                int u, v;
                scanf("%d%d",&u, &v);
                add1(u, v);
                add1(v, u);
            }
            tarjan(1);
            mem(head, -1);
            for(int i=0;i < cnt1; i+=2)  //以连通分量建图  顺便求桥的数量
                if(sccno[Edge1[i].u] != sccno[Edge1[i].v])
                {
                    add2(sccno[Edge1[i].u], sccno[Edge1[i].v]);
                    add2(sccno[Edge1[i].v], sccno[Edge1[i].u]);
                    bridge++;
                }
    
            bfs(sccno[1]);
            bfs(pos);
    
            printf("%d
    ",bridge - maxway);
    
    
        }
    
    
    
        return 0;
    }
    View Code
    自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
  • 相关阅读:
    MongoDB4.0以下版本,同一台电脑安装2个MongoDB服务
    CMake编译Mysql connector C++
    Winsock I/O方法
    查看mysql版本的四种方法(转)
    WorkBench,DELETE 标准语句失败
    Qt 透明对话框 自定义透明度
    QString 分割字符串时产生乱码的问题
    winsock error 相关
    线程的分离状态与结合状态
    Oracle 语法
  • 原文地址:https://www.cnblogs.com/WTSRUVF/p/9307527.html
Copyright © 2020-2023  润新知