zoukankan      html  css  js  c++  java
  • 【ZJOI2004】嗅探器

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

    tarjan求割点的灵活变式

    考虑一下我们求割点的方法:
    寻找以v为根的搜索子树是否能延伸到时间戳小于u的节点来判断u是否为割点

    如果满足了以上条件,那么这个节点u就是割点

    而如果我们以一个信息中心a为根开始搜索,找到一个非根的割点u
    若此时对应的子树根v的时间戳小于b的时间戳,则说明b存在于v为根的这颗子树内

    证明:
    由于dfn随dfs序更新,若还没搜到b,则其dfn为0,或dfn不为0而小于v
    则说明b在进入v以前已经被搜到了
    另外,b等于u的情况是不合题意的

    所以把求割点的方式改一下就好了

    代码:

    #include<bits/stdc++.h>
    #define N 500010
    using namespace std;
    
    int n,u,v,s,t;
    
    struct Edge
    {
    	int next,to;
    }edge[N<<1];
    int cnt=0,head[N];
    
    inline void add_edge(int from,int to)
    {
    	edge[++cnt].next=head[from];
    	edge[cnt].to=to;
    	head[from]=cnt;
    }
    
    int low[N],dfn[N],tms=0;
    bool cut[N];
    void tarjan(int u)
    {
    	low[u]=dfn[u]=++tms;
    	for(register int i=head[u];i;i=edge[i].next)
    	{
    		int v=edge[i].to;
    		if(!dfn[v])
    		{
    			tarjan(v);
    			low[u]=min(low[u],low[v]);
    			if(u==s) continue;
    			else if(dfn[u]<=low[v]&&dfn[v]<=dfn[t]) cut[u]=1;
    		}
    		else low[u]=min(low[u],dfn[v]);
    	}
    }
    
    template<class T>inline void read(T &res)
    {
    	char c;T flag=1;
    	while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
    	while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
    }
    
    int main()
    {
    	read(n);
    	while(true)
    	{
    		read(u);read(v);
    		if(!u&&!v) break;
    		add_edge(u,v);
    		add_edge(v,u);
    	}
    	read(s);read(t);
    	tarjan(s);
    	for(register int i=1;i<=n;++i)
    		if(cut[i]) {printf("%d",i);return 0;}
    	puts("No solution");
    	return 0;
    }
    
  • 相关阅读:
    洛谷P3258 [JLOI2014]松鼠的新家
    洛谷P1306 斐波那契公约数
    bzoj4247:挂饰
    [YTU]_2354 (H 实现复数类中的加运算符重载【C++运算符重载】)
    [YTU]_2440 (C++习题 复数类--重载运算符+,-,*,/)
    [YTu]_2441 (C++习题 复数类--重载运算符2+)
    [YTu]_2439(C++习题 复数类--重载运算符+)
    10.3 重载双目运算符
    10.2.1 关于vc++不支持把类的成员函数定义为类的友元函数的处理
    10.2 运算符重载函数作为类成员函数和友元函数
  • 原文地址:https://www.cnblogs.com/tqr06/p/11640948.html
Copyright © 2011-2022 走看看