【ZJOI2004】嗅探器

练tarjian不错的题,连WA几次后终于会记住tarjian的模板了

原题:

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

1<=n<=100000

恩,首先可以确定答案一定是割顶中的某个点,必要性:因为删掉这个点后s和t就不连通了,所以这个点是割点,但是这个条件不充分,比如下面这个图:

1也是割顶,但是删掉1后s和t依旧联通,也就是说某个割顶可能并不在s到t的必经路上

然而tarjian求出的dfn和low当然不能只拿来求割顶和强连通分量,用处还是挺广泛的

做法:在tarjian中,如果某点x,连接x的某条边的另一端点y,满足x!=s && low[y]>=dfn[x] && dfn[y]<=dfn[t] && low[t]>=dfn[x]

这四个条件的意义分别是:x当然不能是s;x是割点;y要在t之前遍历到;t走第二条路径到不了x(这几个条件描述有点奇怪,看不懂的无视就好= =)

其它几个条件都好理解,y要在t之前遍历到,也就是low[y]>=dfn[x]这个条件我想了很久(而且是试对的)

为什么呐:

充分性:如果x在y之后遍历,则y已经通过某条路径从s到t了(就是tarjian的dfs路径),删掉x后s依旧可以通过这个路径到t,x就不是所求的点

然后就是tarjian的模板辣

小技巧:因为只求最小的答案,所以不用把答案都存下来,ans=min(ans,x);即可

似乎用费用流也可以做?拆点,入点和出点之间权值为1,费用为点的序号,原图中边权值为oo,从s到t费用流,好像是对的?

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 using namespace std;
 7 int read(){int z=0,mark=1;  char ch=getchar();
 8     while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)mark=-1;  ch=getchar();}
 9     while(ch>=‘0‘&&ch<=‘9‘){z=(z<<3)+(z<<1)+ch-‘0‘;  ch=getchar();}
10     return z*mark;
11 }
12 struct ddd{int next,y;}e[2100000];  int LINK[110000],ltop=0;
13 inline void insert(int x,int y){e[++ltop].next=LINK[x];LINK[x]=ltop;e[ltop].y=y;}
14 int n,s,t;
15 int dfn[110000],low[110000],dfs_cnt=0;
16 bool visited[110000];
17 int ans=999999999;
18 void tarjian(int x,int _father){
19     visited[x]=true;
20     dfn[x]=low[x]=++dfs_cnt;
21     for(int i=LINK[x];i;i=e[i].next){
22         if(!visited[e[i].y]){
23             tarjian(e[i].y,x);
24             low[x]=min(low[x],low[e[i].y]);
25             if(x!=s && low[e[i].y]>=dfn[x] && dfn[e[i].y]<=dfn[t] && low[t]>=dfn[x])  ans=min(ans,x);
26         }
27         else if(e[i].y!=_father)  low[x]=min(low[x],dfn[e[i].y]);
28     }
29 }
30 int main(){
31     freopen("ddd.in","r",stdin);
32     freopen("ddd.out","w",stdout);
33     memset(visited,0,sizeof(visited));
34     cin>>n;
35     int _left,_right;
36     for(;;){
37         _left=read(),_right=read();
38         if(!_left && !_right)  break;
39         insert(_left,_right),insert(_right,_left);
40     }
41     cin>>s>>t;
42     tarjian(s,0);
43     if(ans>n)  cout<<"No solution"<<endl;
44     else  cout<<ans<<endl;
45     return 0;
46 }

时间: 2024-10-12 17:03:33

【ZJOI2004】嗅探器的相关文章

Luogu5058 [ZJOI2004]嗅探器

\(\verb|Luogu5058 [ZJOI2004]嗅探器|\) 给定一张 \(n\) 个点, \(m\) 条边的无向图,和两点 \(s,\ t\) ,求 \(s\to t\) 编号最小的必经点(排除 \(s,\ t\) ) \(n\leq100\) tarjan 这题数据范围是可以 \(O(n^3)\) 暴力过的-- 显然只需缩点后的树上 \(bl_s\) 到 \(bl_t\) 上找答案,统计割点贡献即可 然而此题有更简单的做法-- 从 \(s\) 开始 tarjan,点 \(u\) 对答

题解 P5058 【[ZJOI2004]嗅探器】

Solution [ZJOI2004]嗅探器 题目大意:给定一个无向图,求一个编号最小的点\(p\),使得删掉\(p\)后\(s\)和\(t\)不连通 分析:首先我们要明确:点\(p\)一定是割点,因为只有你删掉一个点后图不连通才有可能使得\(s\)和\(t\)不连通,然后我们可以用\(tarjan\)来做这个事情 常规求割点是什么,时间戳\(dfn\),不经过树边可以到达的最小时间戳\(low\) 如果存在\(u\)以及它的子节点\(v\),如果有\(dfn[u] \leq low[v]\)那

[zjoi2004]嗅探器

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

P5058 [ZJOI2004]嗅探器 tarjan割点

这个题是tarjan裸题.最后bfs暴力找联通块就行.(一开始完全写错了竟然得了70分,题意都理解反了...这数据强度...) 题干: 题目描述 某军搞信息对抗实战演习,红军成功地侵入了蓝军的内部网络,蓝军共有两个信息中心,红军计划在某台中间服务器上安装一个嗅探器,从而能够侦听到两个信息中心互相交换的所有信息,但是蓝军的网络相当的庞大,数据包从一个信息中心传到另一个信息中心可以不止有一条通路.现在需要你尽快地解决这个问题,应该把嗅探器安装在哪个中间服务器上才能保证所有的数据包都能被捕获? 输入输

浏览器嗅探器【检测】

在前端开发中经常会遇到一系列兼容性问题,怎样精准地识别出各个浏览器的版本是一件很头痛的问题.下面跟大家分享图个非常实用的浏览器嗅探器的插件,可以让我们在开发中针对各种浏览器作出不同的流程控制.实现浏览器兼容. 代码如下: var BrowserDetect = { init: function () { this.browser = this.searchString(this.dataBrowser) || "An unknown browser"; this.version = t

Python写的嗅探器——Pyside,Scapy

使用Python的Pyside和Scapy写的嗅探器原型,拥有基本框架,但是功能并不十分完善,供参考. 1 import sys 2 import time 3 import binascii 4 from PySide.QtCore import * 5 from PySide.QtGui import * 6 from scapy.all import * 7 8 # Every Qt application must have one and only one QApplication o

浏览器简易嗅探器

document.write(navigator.userAgent); document.write('<br/>'); document.write(navigator.platform); var client = function(){ //引擎 var engine = { ie:false, gecko:false, khtml:false, opera:false, webkit:false, ver:0 }; //浏览器 var browser = { ie:false, fi

矩阵乘法专题3——bzoj 1898 [Zjoi2004]Swamp 沼泽鳄鱼 题解

[原题] 1898: [Zjoi2004]Swamp 沼泽鳄鱼 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 425  Solved: 256 [Submit][Status] Description 潘塔纳尔沼泽地号称世界上最大的一块湿地,它地位于巴西中部马托格罗索州的南部地区.每当雨季来临,这里碧波荡漾.生机盎然,引来不少游客.为了让游玩更有情趣,人们在池塘的中央建设了几座石墩和石桥,每座石桥连接着两座石墩,且每两座石墩之间至多只有一座石桥.这

PYTHON黑帽编程 4.1 SNIFFER(嗅探器)之数据捕获--补充

荒废了一个多月了,重新捡起来,手生了不少.发现在<4.1下>的文章里没有 提到pcap库,实在是不应该. 在网络数据分析的工具中,tcpdump绝对是大名鼎鼎,tcpdump底层是libpcap库,由C语言编写. Pcapy模块则是基于libpcap的Python接口.pcapy在github上的项目地址为: https://github.com/CoreSecurity/pcapy. 下面我们来看看如何使用pcapy实现数据包的捕获. #!/usr/bin/python import pca