[ZJOI2004]嗅探器

题目描述

原题来自:ZJOI 2004

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

输入格式

输入文件的第一行一个整数 n,表示蓝军网络中服务器的数目。

接下来若干行是对蓝军网络的拓扑结构描述,每行是两个整数i ,j,表示编号为 i 和编号为 j 的两台服务器间存在连接(显然连接是双向的),服务器的编号从 1 开始,一行两个 0 表示网络的拓补结构描述结束,再接下来是两个整数 a,b,分别表示两个中心服务器的编号。

输出格式

输出编号。如果有多个解输出编号最小的一个,如果找不到任何解,输出 No solution

样例

样例输入

5
2 1
2 5
1 4
5 3
2 3
5 1
0 0
4 2

样例输出

1

数据范围与提示

1≤n≤100

 

这一题就是割点在加上一点其他的东西

首先,起点不在是1,而是a 

然后我们要找出编号最小的割点,并且使这个割点能断开a和b的连接,所以要特判一下

一个点在割点的基础上,还要满足以下条件

要确保终点是从这一条边上通过的,还有终点不能通往这个点以前的任何点

也就是 

dfn[v] <= dfn[ed] && dfn[u] <= low[ed]

还有记得判断

u != st && u != ed

因为树根是a,很显然嗅探器不会装在中心服务器上(多容易被发现啊),所以不用考虑树根的情况

代码(一如既往的Tarjan)

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std ;

const int N = 110 ;
const int M = 21000 ;

struct edge {
	int v , nxt ;
} e[M<<1] ; int tot , last[N] ;
inline void add ( int u , int v ) {
	e[++tot] = (edge){ v , last[u] } ;
	last[u] = tot ;
	e[++tot] = (edge){ u , last[v] } ;
	last[v] = tot ;
}

int n ; bool flag ;
int id , dfn[N] , low[N] ;
int ans = 999999999 ;
int root ; 
int st , ed ;

void Tarjan ( int u ) {
	dfn[u] = low[u] = ++id ;
	for ( int i = last[u] ; i != -1 ; i = e[i].nxt ) {
		int v = e[i].v ;
		if ( dfn[v] == 0 ) {
			Tarjan( v ) ;
			low[u] = min ( low[u] , low[v] ) ; 
			if ( dfn[u] <= low[v] && dfn[v] <= dfn[ed] && dfn[u] <= low[ed] )
				 if ( u != st && u != ed )
					ans = min ( ans , u ) ;
		}
		else low[u] = min ( low[u] , dfn[v] ) ;
	}
}

int main() {
	cin >> n ; 
	tot = -1 , memset ( last , -1 ,sizeof( last ) ) ;
	int x , y ;
	while ( cin >> x >> y && x != 0 ) add ( x , y ) ;
	cin >> st >> ed ; root = st ;
	id = 0 ; memset ( dfn , 0 , sizeof( dfn ) ) ;
	memset ( low , 0 , sizeof( low ) ) ;
	Tarjan( st ) ;
	if ( ans == 999999999 ) cout << "No solution\n" << endl ;
	else cout << ans << endl ;
	return 0 ;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值