zoukankan      html  css  js  c++  java
  • [机房测试]信息拦截

    Description

    给定一个有向图,按顺序输出是 (1)(n) 路径上的必经点且本身不在一个环内的所有点。

    Solution

    先缩点,建一个新图。对于包含在一个大于等于二的强连通分量内的点一定不会是答案,包含自环的点一定不是答案。从 (1)(n) 分别 bfs 一遍,对能到达的点打上标记。那么必须同时包含两个标记才会成为答案。把不含两个标记的点删掉。又得到一个新图。会发现新图一个特点,就是先从 (1) 出发可以走不同路径,然后汇聚到一个点,再在出发又汇聚到一个点。实际上汇聚到的点就是答案。这些点可以通过拓扑排序求出,当入队时队列是空的,那么这就是一个可以汇聚到的点。
    也可以发现这些点具有割点的性质,可以直接搞成无向图然后求割点。有点卡常。

    #pragma GCC optimize(2)
    #pragma GCC optimize("Ofast")
    #pragma GCC optimize("inline")
    
    #include<stdio.h>
    #include<algorithm>
    #include<vector>
    #include<queue>
    using namespace std;
    
    inline int read(){
        int x=0,flag=1; char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')flag=0;c=getchar();}
        while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-48;c=getchar();}
        return flag? x:-x;
    }
    
    const int N=5e5+7;
    
    queue<int> Q;
    vector<int> g[N],f[N],e[N];
    int timer=0,scc=0,Tp=0,top=0;
    int scc_sz[N],c[N],sta[N],ans[N],Id[N],dfn[N],low[N];
    bool vis1[N],vis2[N],sef[N];
    
    void tarjan(int u){
        dfn[u]=low[u]=++timer;
        sta[++top]=u;
        for(int v:f[u]){
            if(!dfn[v]){
                tarjan(v);
                low[u]=min(low[u],low[v]);
            }else if(!c[v])
                low[u]=min(low[u],dfn[v]);
        }
        if(low[u]==dfn[u]){
            int y; scc++;
            do{scc_sz[c[y=sta[top--]]=scc]++;}while(y!=u);
            if(scc_sz[scc]==1) Id[scc]=y;
            else Id[scc]=0;
        }
    }
    
    void Tarjan(int u){
        int flag=0;
        low[u]=dfn[u]=++timer;
        for(int v:e[u]){
            if(!dfn[v]){
                Tarjan(v);
                low[u]=min(low[u],low[v]);
                if(scc_sz[u]==1&&low[v]>=dfn[u]&&!sef[Id[u]]){
                    flag++; if(flag>1||u!=c[1]) ans[++Tp]=Id[u];
                }
            }
            low[u]=min(low[u],dfn[v]);
        }
    }
    
    int main(){
        freopen("i.in","r",stdin);
        freopen("i.out","w",stdout);
        int T=read();
        while(T--){
            int n=read(),m=read();
            for(int i=1;i<=scc;i++)
                e[i].clear(),scc_sz[i]=0;
            timer=scc=0;
            for(int i=1;i<=n;i++){
                vis1[i]=vis2[i]=sef[i]=0;
                dfn[i]=low[i]=c[i]=0;
                g[i].clear(),f[i].clear();
            }
            for(int i=1,u,v;i<=m;i++){
                u=read(),v=read();
                if(u==v) sef[u]=1;
                else{
                    f[u].push_back(v);
                    g[v].push_back(u);
                }
            }
            tarjan(1);
            if(!dfn[n]){printf("0
    
    ");continue;}
            Q.push(1),vis1[1]=1;
            while(!Q.empty()){
                int u=Q.front(); Q.pop();
                for(int v:f[u]){
                    if(vis1[v]) continue;
                    else Q.push(v),vis1[v]=1;
                }
            }
            Q.push(n),vis2[n]=1;
            while(!Q.empty()){
                int u=Q.front(); Q.pop();
                for(int v:g[u]){
                    if(vis2[v]) continue;
                    else Q.push(v),vis2[v]=1;
                }
            }
            for(int u=1;u<=n;u++){
                if(!vis1[u]||!vis2[u]) continue;
                for(int v:f[u]){
                    if(!vis1[v]||!vis2[v]||c[u]==c[v]) continue;
                    e[c[u]].push_back(c[v]);
                    e[c[v]].push_back(c[u]);
                }
            }
            for(int i=1;i<=scc;i++) dfn[i]=low[i]=0;
            timer=0,Tp=0;
            if(scc_sz[c[n]]==1&&!sef[n]) ans[++Tp]=n;
            Tarjan(c[1]);
            if(scc_sz[c[1]]==1&&!sef[1]) ans[++Tp]=1;
            printf("%d
    ",Tp);
            for(int i=Tp;i;i--) printf("%d ",ans[i]); putchar('
    ');
        }
    }
  • 相关阅读:
    Grunt构建工具插件篇——之less工具
    Grunt构建工具能做哪些事?
    Grunt-几个常用的任务配置,加载,执行的写法
    单元测试任务包括哪些?
    单元测试的概念
    分享Grunt.js配置: watch + liveReload 实时监测文件变化自动刷新浏览器
    如何使用Grunt(好文)
    grunt安装详解及失败处理
    利用 Grunt (几乎)无痛地做前端开发 (一)之单元测试
    Grunt实现自动化单元测试
  • 原文地址:https://www.cnblogs.com/wwlwQWQ/p/15408339.html
Copyright © 2011-2022 走看看