• 题解 P5058 【[ZJOI2004]嗅探器】


    题目链接

    Solution [ZJOI2004]嗅探器

    题目大意:给定一个无向图,求一个编号最小的点(p),使得删掉(p)(s)(t)不连通

    (Tarjan)算法


    分析:首先我们要明确:(p)一定是割点,因为只有你删掉一个点后图不连通才有可能使得(s)(t)不连通,然后我们可以用(tarjan)来做这个事情

    常规求割点是什么,时间戳(dfn),不经过树边可以到达的最小时间戳(low)

    如果存在(u)以及它的子节点(v),如果有(dfn[u] leq low[v])那么(u)就是割点,因为去掉(u)后以(v)为根的子树就和图不连通了

    所以我们以(s)为根做(tarjan),只要在(u)是割点时判断一下(t)在不在以(v)为根的子树内就好了,这个显然是(dfn[v] leq dfn[t])

    #include <cstdio>
    #include <cctype>
    #include <vector>
    using namespace std;
    const int maxn = 128;
    inline int read(){
        int x = 0;char c = getchar();
        while(!isdigit(c))c = getchar();
        while(isdigit(c))x = x * 10 + c - '0',c = getchar();
        return x;    
    }
    vector<int> G[maxn];
    inline void addedge(int from,int to){G[from].push_back(to);}
    int dfn[maxn],low[maxn],tot,s,t,n,ans = 0x7fffffff;
    void tarjan(int u,int faz){
        dfn[u] = low[u] = ++tot;
        for(int v : G[u]){
            if(!dfn[v]){
                tarjan(v,u);
                low[u] = min(low[u],low[v]);
                if(dfn[v] <= dfn[t] && dfn[u] <= low[v] && u != s)ans = min(ans,u);   
            }else if(v != faz && dfn[v])low[u] = min(low[u],dfn[v]);
        }
    }
    int main(){
        n = read();
        for(int u = read(),v = read();u && v;u = read(),v = read())
            addedge(u,v),addedge(v,u);
        s = read(),t = read();
        tarjan(s,-1);
        if(ans != 0x7fffffff)printf("%d
    ",ans); 
        else printf("No solution
    ");
        return 0; 
    }
    
  • 相关阅读:
    面试经验链接汇集
    258. Add Digits
    192. Word Frequency(shell)
    6、字符串循环对角线结构ZigZag Conversion
    5、最长回文子串Longest Palindromic Substring
    idea常用的快捷命令
    JAVA传输概念
    UUID随机字符串
    Bean的加载
    默认标签的解析过程(三)parseDefaultElement
  • 原文地址:https://www.cnblogs.com/colazcy/p/11622427.html
Copyright © 2020-2023  润新知