题目连接
题目描述
某军搞信息对抗实战演习,红军成功地侵入了蓝军的内部网络,蓝军共有两个信息中心,红军计划在某台中间服务器上安装一个嗅探器,从而能够侦听到两个信息中心互相交换的所有信息,但是蓝军的网络相当的庞大,数据包从一个信息中心传到另一个信息中心可以不止有一条通路。现在需要你尽快地解决这个问题,应该把嗅探器安装在哪个中间服务器上才能保证所有的数据包都能被捕获?
题解
题目给我们的第一感觉就是,这个点一定是割点。
终点(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;
}