[ZJOI2004]嗅探器
作者:互联网
[Time Gate]
https://www.luogu.org/problemnew/show/P5058
【解题思路】
首先非常明显的是,只能把服务器建在割点上,因为只有这样,才能捕获到全部的数据。
考虑如何求x,y两点之间的必经的割点。
很明显需要满足4个条件
考虑我们有一个u点,它连了一个v点,那么u点需要满足4个条件。
- u不是起点终点。因为题目要求在中间服务器上建嗅探器。
- u是割点。
废话 - 终点(y)的dfn应该大于等于v点的dfn,因为要确保终点在v点或之后被访问到,即u点为必经的点。
- 终点(y)的low应该大于等于u点的dfn,因为要确保终点必须要经过u点。
【code】
1 #include<cstdio> 2 const int N=1e5+50; 3 const int M=5e5+50; 4 int to[M<<1],las[M<<1],fir[M<<1],cnt; 5 inline void add_edge(int u,int v){ 6 to[++cnt]=v;las[cnt]=fir[u];fir[u]=cnt; 7 to[++cnt]=u;las[cnt]=fir[v];fir[v]=cnt; 8 } 9 int dfn[N],low[N],tot; 10 int gd[N]; 11 int n,m,x,y; 12 int opt,ans=N; 13 inline int max(int u,int v){return u>v?u:v;} 14 inline int min(int u,int v){return u<v?u:v;} 15 void tj(int u){ 16 dfn[u]=low[u]=++tot; 17 for(int i=fir[u];i;i=las[i]){ 18 if(!dfn[to[i]]){ 19 tj(to[i]); 20 low[u]=min(low[u],low[to[i]]); 21 if(u!=x&&u!=y)//不是起点终点 22 if(dfn[u]<=low[to[i]]&&dfn[to[i]]<=dfn[y]&&low[y]>=dfn[x])//满足条件 23 ans=min(ans,u);//更新答案 24 } 25 low[u]=min(low[u],dfn[to[i]]); 26 } 27 } 28 int main(){ 29 scanf("%d",&n); 30 while(scanf("%d%d",&x,&y),x)add_edge(x,y); 31 //建边 32 scanf("%d%d",&x,&y);//读入起点和终点 33 tj(x);//从x点tarjan 34 if(ans!=N)printf("%d\n",ans); 35 else puts("No solution"); 36 }
标签:终点,int,scanf,嗅探器,割点,dfn,ans,ZJOI2004 来源: https://www.cnblogs.com/66dzb/p/11153699.html