zoukankan      html  css  js  c++  java
  • [ZJOI2004]嗅探器

    洛咕

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

    一句话题意:给定(n(n<=100))个点的无向图和两个特殊点,删掉一个点后使得两个特殊点不连通,试求这个点.

    分析:这道题的数据范围真的是小的可爱,如果大一点应该会是道好题.

    直接tarjan求出所有的缩点,然后枚举所有缩点,重新建图(把所有与该缩点有关的边忽略),然后暴力从其中一个特殊点开始跑dfs,如果搜到了另一个特殊点,则该割点不合法,否则直接输出就好了.

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #define ll long long
    using namespace std;
    inline int read(){
        int x=0,o=1;char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')o=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*o;
    }
    const int N=105;
    const int M=10005;
    int a[M],b[M],visit[N];
    int tot,head[N],nxt[M],to[M];
    int top,root,timeclock,dfn[N],low[N],cut[N];
    inline void add(int a,int b){
    	nxt[++tot]=head[a];head[a]=tot;to[tot]=b;
    }
    inline void tarjan(int u){
    	dfn[u]=low[u]=++timeclock;
    	int child=0;
    	for(int i=head[u];i;i=nxt[i]){
    		int v=to[i];
    		if(!dfn[v]){
    			tarjan(v);
    			low[u]=min(low[u],low[v]);
    			if(low[v]>=dfn[u]){
    				++child;
    				if(u!=root||child>=2)cut[u]=1;
    			}
    		}
    		else low[u]=min(low[u],dfn[v]);
    	}
    }
    inline bool dfs(int u,int goal){
    	visit[u]=1;
    	for(int i=head[u];i;i=nxt[i]){
    		int v=to[i];
    		if(visit[v])continue;
    		if(v==goal)return true;
    		if(dfs(v,goal))return true;
    	}
    	return false;
    }
    int main(){
    	int n=read(),m=0;
    	while(1){
    		a[++m]=read(),b[m]=read();
    		if(!a[m]&&!b[m])break;
    		add(a[m],b[m]);add(b[m],a[m]);
    	}
    	int s=read(),t=read();
    	for(int i=1;i<=n;++i)
    		if(!dfn[i])root=i,tarjan(i);
    	for(int i=1;i<=n;++i){
    		if(!cut[i])continue;
    		tot=0;memset(head,0,sizeof(head));
    		for(int j=1;j<=m;++j)
    			if(a[j]!=i&&b[j]!=i){
    				add(a[j],b[j]);add(b[j],a[j]);
    			}
    		memset(visit,0,sizeof(visit));
    		if(!dfs(s,t)){
    			printf("%d
    ",i);
    			return 0;
    		}
    	}
    	puts("No solution");
        return 0;
    }
    
    
  • 相关阅读:
    C/C++定义全局变量/常量几种方法的区别
    可变参数宏__VA_ARGS__
    mysql 命令重命名表RENAME TABLE 句法
    贝尔实验室的历史
    SVN代码回滚
    linux下查看进程占用端口和端口占用进程命令
    php操作mongodb中的ISODate格式日期
    Vim多行缩进技巧
    关于XCode工程中PrefixHead.pch文件的使用
    Object C函数指针@selector
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11389991.html
Copyright © 2011-2022 走看看