1. 程式人生 > >?洛谷5058??ZJOI2004?嗅探器【Tarjan】

?洛谷5058??ZJOI2004?嗅探器【Tarjan】

問題 pan math tel .org 成功 struct 現在 esp

題目連接

【洛谷傳送門】
【LOJ傳送門】

題目描述

某軍搞信息對抗實戰演習,紅軍成功地侵入了藍軍的內部網絡,藍軍共有兩個信息中心,紅軍計劃在某臺中間服務器上安裝一個嗅探器,從而能夠偵聽到兩個信息中心互相交換的所有信息,但是藍軍的網絡相當的龐大,數據包從一個信息中心傳到另一個信息中心可以不止有一條通路。現在需要你盡快地解決這個問題,應該把嗅探器安裝在哪個中間服務器上才能保證所有的數據包都能被捕獲?

題解

題目給我們的第一感覺就是,這個點一定是割點。
終點(y)的dfn應該大於等於v點的dfn,因為要確保終點在v點或之後被訪問到,即u點為必經的點。
終點(y)的low應該大於等於u點的dfn,因為要確保終點必須要經過u點。

一開始被這個\(e\)的重復找了好久的錯誤。誒

代碼

#include <bits/stdc++.h>
#define ms(a, b) memset(a, b, sizeof(a))
#define ll long long
#define ull unsigned long long 
#define ms(a, b) memset(a, b, sizeof(a))
#define inf 0x3f3f3f3f
#define db double 
#define Pi acos(-1)
#define eps 1e-8
#define N 5005
#define M 100005
using namespace std;
template <typename T> T sqr(T x) { return x * x; }
template <typename T> void read(T &x) {
    x = 0; T fl = 1; char ch = 0;
    for (; ch < '0' || ch > '9'; ch = getchar()) if (ch == '-') fl = -1;
    for (; ch >= '0' && ch <= '9'; ch = getchar()) x = (x << 1) + (x << 3) + (ch ^ 48);
    x *= fl;
}
template <typename T> void write(T x) {
    if (x < 0) x = -x, putchar('-');
    if (x > 9) write(x / 10); putchar(x % 10 + '0');
}
template <typename T> void writeln(T x) { write(x); puts(""); }
struct edge {
    int to, nt;
}E[M];
int H[N], dfn[N], low[N];
int sta, end, n, cnt = 0, tot = 0, ans = inf;
void add_edge(int u, int v) {
    E[++ cnt] = (edge){v, H[u]}; 
    H[u] = cnt;
}
void tarjan(int u) {
    dfn[u] = low[u] = ++ tot;
    for (int e = H[u]; e; e = E[e].nt) {
        int v = E[e].to;
        if (!dfn[v]) {
            tarjan(v);
            low[u] = min(low[u], low[v]);
            if (u != sta && u != end) 
            if (dfn[u] <= low[v] && dfn[v] <= dfn[end] && low[end] >= dfn[sta]) 
                ans = min(ans, u);
        }
        low[u] = min(low[u], dfn[v]);
    }
}
int main() {
    read(n);
    while (1) { int u, v; read(u); read(v); if (!u && !v) break; add_edge(u, v); add_edge(v, u); }
    read(sta); read(end);
    tarjan(sta); 
    if (ans == inf) puts("No solution"); else writeln(ans);
    return 0;
}

?洛谷5058??ZJOI2004?嗅探器【Tarjan】