ICode9

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

P5058 [ZJOI2004]嗅探器 tarjan割点

2019-02-24 08:54:13  阅读:256  来源: 互联网

标签:tarjan int 嗅探器 蓝军 编号 服务器 ZJOI2004 include


这个题是tarjan裸题。最后bfs暴力找联通块就行。(一开始完全写错了竟然得了70分,题意都理解反了。。。这数据强度。。。)

题干:

题目描述

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

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

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

输出格式:

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

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(register int i = a;i <= n;++i)
#define lv(i,a,n) for(register int i = a;i >= n;--i)
#define clean(a) memset(a,0,sizeof(a))
const int INF = 1 << 30;
typedef long long ll;
typedef double db;
template <class T>
void read(T &x)
{
    char c;
    bool op = 0;
    while(c = getchar(), c < '0' || c > '9')
        if(c == '-') op = 1;
    x = c - '0';
    while(c = getchar(), c >= '0' && c <= '9')
        x = x * 10 + c - '0';
    if(op) x = -x;
}
template <class T>
void write(T x)
{
    if(x < 0) putchar('-'), x = -x;
    if(x >= 10) write(x / 10);
    putchar('0' + x % 10);
}
const int N = 1e5 + 5;
struct node
{
    int l,r,nxt;
}a[N * 5];
int n,A,B;
int x,y;
int lst[N],len,cnt = 0,dfn[N],low[N];
int cut[N],child = 0;
void add(int x,int y)
{
//    cout<<x<<" "<<y<<endl;
    a[++len].l = x;
    a[len].r = y;
    a[len].nxt = lst[x];
    lst[x] = len;
}
void tarjan(int x,int fa)
{
    dfn[x] = low[x] = cnt++;
    for(int k = lst[x];k;k = a[k].nxt)
    {
        int y = a[k].r;
        if(!dfn[y])
        {
            tarjan(y,x);
            low[x] = min(low[x],low[y]);
            if(low[y] >= dfn[x] && x != fa)
            {
                cut[x] = 1;
            }
            if(x == fa)
            {
                child++;
            }
        }
        low[x] = min(low[x],dfn[y]);
    }
    if(child >= 2 && x == fa)
    {
        cut[x] = 1;
    }
}
bool vis[N];
bool check(int x)
{
    clean(vis);
    queue <int> q;
    vis[A] = 1;
    q.push(A);
    while(!q.empty())
    {
        int now = q.front();
        q.pop();
//        cout<<now<<"???"<<endl;
        if(now == x) continue;
        for(int k = lst[now];k;k = a[k].nxt)
        {
            int y = a[k].r;
            if(vis[y] == 1) continue;
            if(y == x) continue;
            if(y == B) return false;
            vis[y] = 1;
            q.push(y);
        }
    }
    return true;
}
int main()
{
    read(n);
    while(1)
    {
        read(x);read(y);
        if(x == 0 && y == 0)
        {
            break;
        }
        add(x,y);
        add(y,x);
    }
    read(A);read(B);
    duke(i,1,n)
    {
        if(!dfn[i])
        {
            tarjan(i,i);
        }
    }
    duke(i,1,n)
    {
        if(i == A || i == B) continue;
        if(cut[i])
        {
//            cout<<i<<endl;
            if(check(i) == true)
            {
                printf("%d\n",i);
                return 0;
            }
        }
    }
    printf("No solution\n");
    return 0;
}

 

标签:tarjan,int,嗅探器,蓝军,编号,服务器,ZJOI2004,include
来源: https://www.cnblogs.com/DukeLv/p/10425290.html

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

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

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

ICode9版权所有