• ContestHunter#24-C 逃不掉的路


    Description:

    求无向图的必经边

     思路:一眼题 将无向图缩成树,然后求两点树上距离

    #include<iostream>
    #include<vector> 
    #include<cstring>
    using namespace std;
    const int N = 2e5 + 10;
     
    int head[N], now = 1;
    struct edges{
        int to, next;
    }edge[N<<1];
    void add(int u,int v){ edge[++now] = {v, head[u]}; head[u] = now;}
     
    int n, m, dfn[N], low[N], cnt, tot, dict[N], Q, ans[N], dis[N], fa[N], vis[N];
    bool bri[N<<1];
    struct query{
        int to, id;
    };
    vector<query> q[N];
    void q_add(int u, int v, int y){ q[u].push_back({v, y}); q[v].push_back({u, y}); }
    void tarjan(int x, int in_edge){
        dfn[x] = low[x] = ++cnt;
        for(int i = head[x]; i; i = edge[i].next){
            int v = edge[i].to;
            if(!dfn[v]){
                tarjan(v, i);
                low[x] = min(low[x], low[v]);
                if(low[v] > dfn[x]) bri[i] = bri[i ^ 1] = 1;
            }
            else if(i != (in_edge ^ 1)) low[x] = min(low[x], dfn[v]);
        }
    }
     
    void dfs(int x){
        dict[x] = tot; vis[x] = 1;
        for(int i = head[x]; i; i = edge[i].next){
            int v = edge[i].to;
            if(vis[v] || bri[i]) continue;
            dfs(v);
        }
    }
    int get(int x){
        if(x != fa[x]) return fa[x] = get(fa[x]);
        return x;
    }
    void LCA(int x){
        vis[x] = 1;
        for(int i = head[x]; i; i = edge[i].next){
            int v = edge[i].to;
            if(vis[v]) continue;
            dis[v] = dis[x] + 1;
            LCA(v);
            fa[v] = x;
        }
        for(int i = 0; i < q[x].size(); i++){
            int v = q[x][i].to, id = q[x][i].id;
            if(vis[v] == 2){
                int lca = get(v); 
                ans[id] = min(ans[id], dis[x] + dis[v] - 2 * dis[lca]);
            }
        }
        vis[x] = 2;
    }
    struct input{
        int x, y;
    }in[N];
    int main(){
        scanf("%d%d", &n, &m);
        int x, y;
        for(int i = 1; i <= m; i++){
            scanf("%d%d", &x, &y);
            in[i] = {x, y};
            add(x, y); add(y, x);
        }
        for(int i = 1; i <= n; i++)
          if(!dfn[i]) tarjan(i, 0);
        for(int i = 1; i <= n; i++)
          if(!vis[i]) tot++, dfs(i);
        memset(head, 0, sizeof(head));
        memset(edge, 0, sizeof(edge)); now = 0;
        memset(vis, 0, sizeof(vis));
        for(int i = 1; i <= m; i++){
            x = dict[in[i].x], y = dict[in[i].y];
            if(x == y) continue;
            add(x, y), add(y, x);
        }
        scanf("%d", &Q);
        for(int i = 1; i <= Q; i++){
            scanf("%d%d", &x, &y);
            x = dict[x], y = dict[y];
            if(x == y) ans[i] = 0;
            else{
                q_add(x, y, i);
                ans[i] = 1e9;
            }
        }
        for(int i = 1; i <= n; i++) fa[i] = i;
        LCA(1);
        for(int i = 1; i <= Q; i++)
          printf("%d
    ", ans[i]);
        return 0;
    }
    View Code
  • 相关阅读:
    毕业设计
    毕业设计
    毕业设计
    毕业设计
    layui table
    毕业设计
    Echart图标统计
    Pxe自动化安装
    Linux运维常用脚本整理
    Zabbix 一键部署
  • 原文地址:https://www.cnblogs.com/Rorshach/p/8724900.html
Copyright © 2020-2023  润新知