[ZJOI2004]嗅探器

题目描述

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

输入格式

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

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

输出格式

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


加个判断:另一个服务器是否在路径上

 

#include<bits/stdc++.h>
#define re return
#define ll long long
#define inc(i,l,r) for(int i=l;i<=r;++i) 
using namespace std;
template<typename T>inline void rd(T&x)
{
    char c;bool f=0;
    while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
    x=c^48;
    while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
    if(f)x=-x;
}

const int maxn=5005,maxm=10005;
ll n,m,k=1,rs,GD,tot,col,hd[maxn];
ll low[maxn],dfn[maxn],isgd[maxn],d[maxn];
struct node{
    int to,nt;
}e[maxm<<1];

ll ans1,ans=1;

inline void add(int x,int y)
{
    e[++k].to=y;e[k].nt=hd[x];hd[x]=k;
    e[++k].to=x;e[k].nt=hd[y];hd[y]=k;
}

stack<int>s;

inline void tarjan(int x,int fa)
{
    dfn[x]=low[x]=++tot;
    
    for(int i=hd[x];i;i=e[i].nt)
    {
        int v=e[i].to;
        if(v==fa)continue;
        if(!dfn[v])
        {
            tarjan(v,x);
            d[x]+=d[v];
            //d的作用类似于用查分判断这个点是否在
            //两个中心服务器的路径上 
            low[x]=min(low[x],low[v]);
            if(!fa)++rs;
            else if(dfn[x]<=low[v]&&d[v])//是路径上的割点 
                isgd[x]=1;
        }
        else low[x]=min(dfn[v],low[x]);
    }
}

int main()
{
    freopen("in.txt","r",stdin);
    
    int x,y;

        rd(n);
        while(2333)
        {
            rd(x),rd(y);
            if(x==0&&y==0)break;
            add(x,y);
        }
    
        rd(x),rd(y);
        d[y]=1;
        tarjan(x,0);

        inc(i,1,n)
        if(isgd[i]&&d[i])
        {
            printf("%d",i);
            re 0;
        }
        printf("No solution");
    

    re 0;
}

 

posted @ 2019-08-27 21:06  凉如水  阅读(139)  评论(0编辑  收藏  举报