• kuangbin专题 专题九 连通图 POJ 3177 Redundant Paths


    题目链接:https://vjudge.net/article/371?tdsourcetag=s_pcqq_aiomsg

    题目:给定一个连通图,题目说,任意两个点至少有一条路线可以相互到达,

    为保证任意两点有完全不同的路线(点可以相同,边不能相同)可以相互到达至少需要加几条边。

    思路:tarjan缩点,之后重构图,找出度数为1的scc个数scc_cnt,这些点相互连接,答案可以得出是 (scc_cnt+1)/2。

    两组样例:

    n = 5 ,m = 4  |  (1 2)  (1 3) )(1 4) (1 5)

    n = 8, m = 9  | (1 2) (1 4) (2 3) (3 4) (4 5) (5 6) (6 7) (5 8) (7 8 )

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    const int N = (int)5e3+10;
    int head[N],dfn[N],low[N],scc_no[N],s[N],du[N];
    int n,m,tot,tim,scc,top;
    struct node{
        int to;
        int nxt;
    }e[N << 2];
    
    inline void add(int u,int v){
        e[tot].to = v;
        e[tot].nxt = head[u];
        head[u] = tot++;
    }
    
    void tarjan(int now,int pre){
        dfn[now] = low[now] = ++tim;
        s[top++] = now;
        
        //这里有情况,两点之间可能>1条路直接连接
        //所以,需要处理下边的重复问题
        int to,pre_cnt = 0;
        for(int o = head[now]; ~o; o = e[o].nxt){
            to = e[o].to;
            //只是一条无向边,处理一下
            if(to == pre && pre_cnt == 0){
                pre_cnt = 1;
                continue;
            }
            if(!dfn[to]){
                tarjan(to,now);
                low[now] = min(low[now],low[to]);
            }
            else low[now] = min(low[now],dfn[to]);
        }
    
        if(dfn[now] == low[now]){
            ++scc;
            int x;
            do{
                x = s[--top];
                scc_no[x] = scc;
            }while(now != x);
        }
    }
    
    void rebuild(){
        int to;
        for(int now = 1; now <= n; ++now){
            for(int o = head[now]; ~o; o = e[o].nxt){
               to = e[o].to;
               if(scc_no[now] != scc_no[to]){
                    ++du[scc_no[now]];
                    ++du[scc_no[to]];
               }
            }
        }
    }
    
    void solve(){
        int p = 0;
     //   cout << scc << endl;
     
        //度数为什么是2的,因为是无向图,其实除2就是度数为1了
        for(int i = 1; i <= scc; ++i)
            if(du[i] == 2) ++p;
      //  cout << p << endl;
    
        printf("%d
    ",(p+1)/2);
    }
    
    int main(){
    
        int u,v;
        scanf("%d%d",&n,&m);
        for(int i = 1;i <= n; ++i) head[i] = -1;
        for(int i = 0; i < m; ++i){
            scanf("%d%d",&u,&v);
            add(u,v); add(v,u);
        }
        tarjan(1,1);
        rebuild();
        solve();
    
        return 0;
    }

            

  • 相关阅读:
    python连接数据库异步存储
    pythonscrapy之MySQL同步存储
    头有点大
    scrapy反爬虫
    《猫抓老鼠》
    Linux下系统监控工具nmon
    探索式测试学习资料
    开始探索式测试学习之前的思考
    Software Quality Characteristics 软件质量特性
    自动化测试整理 STAF/STAX & Robot Framework
  • 原文地址:https://www.cnblogs.com/SSummerZzz/p/12199411.html
Copyright © 2020-2023  润新知