ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

题解 P5058 [ZJOI2004]嗅探器

2020-06-20 14:07:51  阅读:218  来源: 互联网

标签:exb read 题解 嗅探器 low && ZJOI2004 now true


一道 \(tarjan\) 题

蓝军共有两个信息中心,红军计划在某台中间服务器上安装一个嗅探器,从而能够侦听到两个信息中心互相交换的所有信息。

也就是说,\(a\) 到 \(b\) 的所有路径必须经过 那个中间服务器。

-----> 如果删去那个中间服务器,\(a\) 与 \(b\) 不联通。

-----> 那个中间服务器是一个割点。(一个特殊的割点)

假设用 \(now\) 表示当前结点, \(v\) 表示儿子。

\(exa[now]\) 表示当前结点所在子树中有无 \(a\)

\(exb[now]\) 同理

那么当且仅当以下条件全部发生时,\(now\) 可以更新 \(ans\)

  • now为割点(这是显然的,上面已分析)
  • 在以上条件成立时,\(a\) 与 \(b\) 只能有一个在 \(v\) 的子树内(因为删去 \(now\) 后 \(v\) 的子树的点与其他点不联通)(如果a,b都不在v内,now也可能是答案,但这是通过其他子树来实现的)。
  • now!=a&&now!=b(一定不要忘记)(看清题目)

Code

#include<cstdio>
#include<iostream>
#define LL long long
#define rint register int
using namespace std;
namespace FastIO
{
char c;
bool sign;
template<class T>
inline void read(T &x)
{
	x=0;
	sign=false;
	for(c=getchar();c<'0'||c>'9';c=getchar()) 
		if(c=='-') 
			sign=true;
	for(;c>='0'&&c<='9';c=getchar()) 
		x=(x<<1)+(x<<3)+(c&15);
	if(sign) x=~x+1;
	return;
}
}
using FastIO::read;
//======================================
const int N=2e5+5;
const int M=1e6+5;
int one[N];
int ver[M],Next[M];
int tot=0;
inline void AddEdge(const int &a,const int &b)
{
	tot++;
	Next[tot]=one[a];
	one[a]=tot;
	ver[tot]=b;
	return;
}
//======================================
int n;
int a,b;
int dfn[N],low[N],times=0;
bool exa[N],exb[N]; // 在搜索树的子树中有没有 a,b
int ans=N+3;
void tarjan(int now,const int &fa)
{
	dfn[now]=low[now]=++times;
	rint i,v,child=0;
	for(i=one[now];i>0;i=Next[i]) {
		v=ver[i];
		if(!dfn[v]) {
			child++;
			tarjan(v,now);
			low[now]=min(low[now],low[v]);
			if(exa[v]) exa[now]=true;
			if(exb[v]) exb[now]=true; 
			if((fa==-1&&child>1)||(fa!=-1&&low[v]>=dfn[now]))
				if(exa[v]^exb[v]&&now!=a&&now!=b) // !!!
					ans=min(ans,now);
		}
		else if(v!=fa) 
			low[now]=min(low[now],dfn[v]);
	}
	return;
} 
int main()
{
//	freopen("1.in","r",stdin);
	rint i;
	int x,y;
	read(n);
	while(true) {
		read(x); read(y);
		if(x==0&&y==0) 
			break;
		AddEdge(x,y);
		AddEdge(y,x);
	}
	read(a); read(b);
	exa[a]=true;
	exb[b]=true;
//	tarjan(a,-1);
	for(i=1;i<=n;i++) 
		if(dfn[i]==0) 
			tarjan(i,-1);
	if(ans==N+3) 
		puts("No solution");
	else printf("%d\n",ans);
	return 0;
}

标签:exb,read,题解,嗅探器,low,&&,ZJOI2004,now,true
来源: https://www.cnblogs.com/cjl-world/p/13168492.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有