zoukankan      html  css  js  c++  java
  • 嗅探器

    https://loj.ac/problem/10101

    题目描述

      给出一张无向图和两个点a、b,求是否能找出一个点使得a到b的所有路径都要经过这个点。

    思路

      路径都必须经过,很容易想到割点。但由于要求的是a到b的路径中,那么就有几种情况:

      ①若a、b在同一个点双联通分量中,显然不存在这样一个节点。

      ②若a、b不在一个点双联通分量中,那么我们可以选择缩点后两点所在分量的树上简单路径上的所有割点。

      因此我们只需要tarjan(a),以a为根搜索下去,在判断割点u(u不为树根)时加上条件dfn[b]≥dfn[v]即可,意味着b在v的搜索次序后,那么显然就可以通过这个割点来监视所有情报。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N=110,M=N*N;
    
    struct Edge
    {
        int to,nxt;
    }e[M];
    
    int nxt[M],to[M],tot,head[N];
    void add_edge(int x,int y)
    {
        nxt[++tot]=head[x];
        head[x]=tot;
        to[tot]=y;
    }
    
    int poi[N],tt;
    void add(int x,int y)
    {
        e[++tt].nxt=poi[x];
        poi[x]=tt;
        e[tt].to=y;
    }
    
    int dfn[N],low[N],idx,root,ans=0x7fffffff,a,b;
    void tarjan(int u)
    {
        dfn[u]=low[u]=++idx;
        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(root!=u&&dfn[u]<=low[v]&&dfn[b]>=dfn[v])
                    ans=min(ans,u);
            }
            else low[u]=min(low[u],dfn[v]);
        }
    }
    int main() 
    {
        int n;
        scanf("%d",&n);
        int x,y;
        while(scanf("%d%d",&x,&y)&&(x|y))
        {
            add_edge(x,y);
            add_edge(y,x);
        }
        scanf("%d%d",&a,&b);
        root=a;
        tarjan(a);
        if(ans!=0x7fffffff)
            printf("%d",ans);
        else printf("No solution");
    }
  • 相关阅读:
    四轴PID思路整理
    STM32输入捕获TIM2四通道
    四轴和遥控器的对应
    四层板学习(二)
    四层板学习(一)布线前的准备
    冲突的处理方法
    散列表
    重设置电脑时间
    深圳销量统计源码分析
    源码分析
  • 原文地址:https://www.cnblogs.com/fangbozhen/p/11741038.html
Copyright © 2011-2022 走看看