zoukankan      html  css  js  c++  java
  • 判负环

    众所周知,SPFA可以判负环。如果采用BFS,那么存在负环的充要条件就是一个点入队超过总点数次。但不难看出,这样的方法效率是很低的。

    我们考虑DFS。

    如果题目只要求判断负环,我们便有一种效率稍高的方法:将dis数组初始化为0,对每个点跑一遍dfs即可,如果能在一次搜索中搜到重复的点,那么负环就存在。

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 2000000+10 
    typedef long long LL;
    struct ed{int v,next;LL w;}edge[MAXN*2];
    int n,m,tot,head[MAXN],vis[MAXN];
    bool flag=false;
    LL dis[MAXN];
    void add(int u,int v,LL w){
        edge[++tot].v=v;
        edge[tot].w=w;
        edge[tot].next=head[u];
        head[u]=tot;
    }
    void dfs(int u){
        if(flag)return;
        vis[u]=1;
        for(int i=head[u];i;i=edge[i].next){
            int v=edge[i].v;
            if(flag)return;
            if(dis[u]+edge[i].w<dis[v]){
                dis[v]=dis[u]+edge[i].w;
                if(vis[v]){
                    flag=true;
                    return;
                }
                else dfs(v);
            }
        }
        vis[u]=0;
    }
    void init(){
        tot=0;
        memset(head,0,sizeof(head));
        memset(vis,0,sizeof(vis));
        memset(dis,0,sizeof(dis));    
    }
    int main(){
        int T;
        scanf("%d",&T);
        while(T--){
            init();    
            scanf("%d%d",&n,&m);
            for(int i=1;i<=m;i++){
                int u,v;LL w;
                scanf("%d%d%lld",&u,&v,&w);
                add(u,v,w);
                if(w>0)add(v,u,w);
            }
            flag=false;
            for(int i=1;i<=n;i++){
                dfs(i);
                if(flag)break;
            }
            puts(flag?"YES":"NO");
        }
        return 0;
    }
  • 相关阅读:
    HookLogger的使用
    文件创建与读写练习
    存储流练习2
    闭包
    Console命令详解,让调试js代码变得更简单
    清除浮动的3种方法
    js继承的几种实现方法
    题一
    题二
    十个修复IE6下bug技巧
  • 原文地址:https://www.cnblogs.com/NINGLONG/p/7776515.html
Copyright © 2011-2022 走看看