码迷,mamicode.com
首页 > 其他好文 > 详细

题解 P5058 【[ZJOI2004]嗅探器】

时间:2019-10-04 16:52:25      阅读:79      评论:0      收藏:0      [点我收藏+]

标签:oid   才有   rom   连通   题解   const   ffffff   amp   删掉   

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]嗅探器】

标签:oid   才有   rom   连通   题解   const   ffffff   amp   删掉   

原文地址:https://www.cnblogs.com/colazcy/p/11622427.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!