题解 P5058 [ZJOI2004]嗅探器

Posted colazcy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解 P5058 [ZJOI2004]嗅探器相关的知识,希望对你有一定的参考价值。

Solution [ZJOI2004]嗅探器

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

分析:首先我们要明确:\(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\n",ans); 
    else printf("No solution\n");
    return 0; 

以上是关于题解 P5058 [ZJOI2004]嗅探器的主要内容,如果未能解决你的问题,请参考以下文章

[zjoi2004]嗅探器

ZJOI2004嗅探器

网络嗅探器怎么用啊?

如何防止嗅探器的探测?

Python写的嗅探器——Pyside,Scapy

Python黑帽编程 4.1 Sniffer(嗅探器)之数据捕获(上)