• 【模板】负环判定


    存在负环,即:执行 spfa 算法时,一个点被更新了 N 次或 N 次以上,那么一定存在负环。由于无向图任意两点间的简单路径经过的边数均小于 N,且 B-F 算法在第 i 轮迭代结束时可以求得经过不超过 i 条边得到的单源最短路。因此, 在 N-1 次迭代时一定可以将所有点的最短路均求出。
    更高效率的做法是记录一个点最短路经过的边数,若边数大于等于了 N,则证明出现了负环。

    代码如下

    #include <bits/stdc++.h>
    using namespace std;
    const int maxv=2010;
    const int maxe=3010;
    
    inline int read(){
    	int x=0,f=1;char ch;
    	do{ch=getchar();if(ch=='-')f=-1;}while(!isdigit(ch));
    	do{x=x*10+ch-'0';ch=getchar();}while(isdigit(ch));
    	return f*x;
    }
    
    struct node{
    	int nxt,to,w;
    }e[maxe<<1];
    int tot=1,head[maxv];
    inline void add_edge(int from,int to,int w){
    	e[++tot]=node{head[from],to,w},head[from]=tot;
    }
    
    int n,m,d[maxv],cnt[maxv];
    bool in[maxv];
    
    bool spfa(){
    	queue<int> q;
    	memset(d,0x3f,sizeof(d));
    	memset(in,0,sizeof(in));
    	d[1]=0,in[1]=1,q.push(1);
    	while(q.size()){
    		int u=q.front();q.pop(),in[u]=0;
    		if(cnt[u]>=n)return 1;
    		for(int i=head[u];i;i=e[i].nxt){
    			int v=e[i].to,w=e[i].w;
    			if(d[v]>d[u]+w){
    				d[v]=d[u]+w,cnt[v]=cnt[u]+1;
    				if(!in[v])q.push(v),in[v]=1;
    			}
    		}
    	}
    	return 0;
    }
    
    void read_and_parse(){
    	n=read(),m=read();
    	for(int i=1,x,y,z;i<=m;i++){
    		x=read(),y=read(),z=read();
    		if(z>=0)add_edge(x,y,z),add_edge(y,x,z);
    		else add_edge(x,y,z);
    	}
    }
    
    void solve(){
    	puts(spfa()?"YE5":"N0");
    }
    
    void init(){memset(head,0,sizeof(head)),memset(cnt,0,sizeof(cnt)),tot=1;}
    
    int main(){
    	int T=read();
    	while(T--){
    		init();
    		read_and_parse();
    		solve();
    	}
    	return 0;
    }
    
  • 相关阅读:
    图书管理系统登录界面
    图书管理系统的管理者界面
    图书管理系统-servlet层
    图书管理系统的dao层
    Linux 内核优化
    第十一章 Nginx之服务代理
    第十章 Nginx之LNMP拆分
    第九章 Nginx之LNMP架构
    第八章 Nginx常用模块
    第七章 WEB服务之Nginx
  • 原文地址:https://www.cnblogs.com/wzj-xhjbk/p/10544632.html
Copyright © 2020-2023  润新知