• 环相关问题


    判环

    有向图

    如果只有正(负)边权的图,拓扑即可,如果存在点没有入队,那么一定是存在环的。也可以用 tarjan,如果存在一个 scc 不是单独的一个点,那么就有环。

    /* Case1: topo */
    bool check(){
        for(int i=1;i<=n;i++)
            if(!in[i]) Q.push(i);
        while(!Q.empty()){
            int u=Q.front(); Q.pop();
            for(int i=head[u];i;i=e[i].next)
                if(!(--in[e[i].to])) Q.push(e[i].to);
        }
        for(int i=1;i<=n;i++)
            if(in[i]) return 1;
        return 0;
    }
    

    否则的话考虑 SPFA,建一个超级源点,可以一次性判环。

    inline bool SPFA(){
        for(int i=1;i<=n;i++)
            add(n+1,i,0),dis[i]=inf;
        dis[n+1]=0; Q.push(n+1);
        while(!Q.empty()){
            int u=Q.front(); Q.pop(); vis[u]=0;
            for(int i=head[u];i;i=e[i].next){
                int v=e[i].to;
                if(dis[v]>dis[u]+e[i].dis){
                    dis[v]=dis[u]+e[i].dis;
                    in[v]=in[u]+1;
                    if(in[v]>n) return 1;
                    if(!vis[v]) vis[v]=1,Q.push(v);
                }
            }
        }
        return 0;
    }
    

    无向图

    考虑 dfs ,如果遇到返祖边则检查一下当前记录的 dis[u]+e[i].dis 是否为负(正),即可判断。

    基环树

    注意内向树和外向树有点小区别实现的时候需要注意。

    void dfs(int u){
        static bool tag=0;
        sta[++top]=u;
        for(int i=head[u];i;i=e[i].next){
            int v=e[i].to;
            if(v==fa[u]) continue;
            if(ins[v]){
                tag=1; int y;
                do{
                    imp[y=sta[top--]]=1;
                    a[++m]=y;
                }while(y!=v);
                return ;
            }
            ins[u]=1,fa[v]=u,dfs(v),ins[u]=0;
            if(tag) return ;
        }
        top--;
    }
    
  • 相关阅读:
    nodejs-supervisor
    javascript数组操作(创建、元素删除、数组的拷贝)
    mysql索引优化-order/group
    php-kafka
    大流量高并发解决方案
    MySQL数据类型和常用字段属性总结
    php一致性hash算法
    面试中的排序算法总结
    PHP的运行机制与原理(底层)
    Mysql中的锁机制
  • 原文地址:https://www.cnblogs.com/wwlwQWQ/p/10395408.html
Copyright © 2020-2023  润新知