⌈洛谷5058⌋⌈ZJOI2004⌋嗅探器【Tarjan】

题目连接

【洛谷传送门】
【LOJ传送门】

题目描述

某军搞信息对抗实战演习,红军成功地侵入了蓝军的内部网络,蓝军共有两个信息中心,红军计划在某台中间服务器上安装一个嗅探器,从而能够侦听到两个信息中心互相交换的所有信息,但是蓝军的网络相当的庞大,数据包从一个信息中心传到另一个信息中心可以不止有一条通路。现在需要你尽快地解决这个问题,应该把嗅探器安装在哪个中间服务器上才能保证所有的数据包都能被捕获?

题解

题目给我们的第一感觉就是,这个点一定是割点。
终点(y)的dfn应该大于等于v点的dfn,因为要确保终点在v点或之后被访问到,即u点为必经的点。
终点(y)的low应该大于等于u点的dfn,因为要确保终点必须要经过u点。
一开始被这个 e e 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值