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

    一开始看到它的时候,想都没想直接CV了割点的模板。结果是这样的:

    再次读题,发现是只用找u->v路径上的最小割点,改一下就A了

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e6+7;
    struct node{
        int nxt;
        int to;
    }edge[2*maxn];
    int head[maxn],cnt,tot;
    bool check[maxn];
    int cut[maxn];
    void add(int x,int y){
        edge[++cnt].nxt=head[x];
        edge[cnt].to=y;
        head[x]=cnt;
    }
    int n,m,x,y;
    int dfn[maxn],low[maxn],sta[maxn],Time;
    int a,b;
    void dfs(int x){
        dfn[x]=low[x]=++Time;
        //int son=0;//统计以x为根的子树个数 
        for(int i=head[x];i;i=edge[i].nxt){
            int v=edge[i].to;
            if(!dfn[v]){
                dfs(v);
                low[x]=min(low[x],low[v]);
                if(x!=a&&low[v]>=dfn[x]&&dfn[v]<=dfn[b]) check[x]=true;//如果其不是根节点,但是它的孩子能回溯到的最近时间比其大,说明其子必须要经过它,所以去掉他则原图不会联通,所以是割点。还有一个细节就是v的dfn要小于b的dfn,因为点必须在ab之间
              }
              else low[x]=min(low[x],dfn[v]); //这个非常重要,一定要是和他能走到得点的时间做比较,而不能和它们的low比较,否则可能会搜不到割点 
        }
        //if(x==fa&&son>=2) check[fa]=true;//如果节点是根节点并且子树大于2,是割点 
    }
    int main()
    {
        scanf("%d",&n);
        while(1){
            scanf("%d%d",&x,&y);
            if(x==0&&y==0) break;
            add(x,y);
            add(y,x);
        }
        scanf("%d%d",&a,&b);
        dfs(a); 
        for(int i=1;i<=n;i++){
            if(check[i]){
                printf("%d
    ",i);
                return 0;
            }
        }
        printf("No solution
    ");
        return 0; 
    }  
  • 相关阅读:
    ⛅剑指 Offer 11. 旋转数组的最小数字
    ✨Shell脚本实现Base64 加密解密
    Linux配置Nginx
    378. Kth Smallest Element in a Sorted Matrix
    875. Koko Eating Bananas
    278. First Bad Version
    704. Binary Search
    69. Sqrt(x)
    LeetCode 110 判断平衡二叉树
    LeetCode 43 字符串相乘
  • 原文地址:https://www.cnblogs.com/LJB666/p/11175284.html
Copyright © 2011-2022 走看看