Loading

洛谷-P5058 嗅探器

嗅探器

tarjan 割点

考虑以 \(a\) 作为根进行一次 \(tarjan\) 的搜索,会发现只有到 \(b\) 的路径上的割点才有可能是最终的答案

因此考虑一边标记这个路径,一边在这个路径上找割点即可

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn = 2e5 + 10;
vector<int>gra[maxn];
int dfn[maxn], low[maxn], tp = 0;
int vis[maxn], minn_ans = maxn;
int a, b;

void tarjan(int now)
{
    low[now] = dfn[now] = ++tp;
    int f = 0, v = 0;
    for(int nex : gra[now])
    {
        if(dfn[nex] == 0)
        {
            tarjan(nex);
            low[now] = min(low[now], low[nex]);
            if(low[nex] >= dfn[now] && vis[nex])
                f = 1;
            if(vis[nex]) v = 1;
        }
        else
            low[now] = min(dfn[nex], low[now]);
    }
    if(now == b || v) vis[now] = 1;
    if(f && now != a && now != b)
        minn_ans = min(minn_ans, now);
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin >> n;
    
    while(cin >> a >> b && (a | b))
    {
        gra[a].push_back(b);
        gra[b].push_back(a);
    }
    cin >> a >> b;
    tarjan(a);
    if(minn_ans != maxn) cout << minn_ans << endl;
    else cout << "No solution" << endl;
    return 0;
}

posted @ 2022-08-26 23:31  dgsvygd  阅读(19)  评论(0编辑  收藏  举报