• P3385 【模板】负环


    题目地址


    易错点:

    • 由于是普通队列,不需要判断Node的大小关系,所以可以记录当前点是否在队列中(vis[]),如果在则不需要重复入队.
    • 判断队列前端和后端哪个dis更小,让更小的在前面(swap(q.front(),q.back()))是一个有效剪枝.
    • 数据清空时邻接表(head[])必须清空,但边只需要重置edgeCnt即可.

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int MAXN=4e3,MAXM=6e3;
    struct Edge{
    	int from,to,w,nxt;
    }e[MAXM];
    int head[MAXN],edgeCnt=0;
    void addEdge(int u,int v,int w){
    	e[++edgeCnt].from=u;
    	e[edgeCnt].to=v;
    	e[edgeCnt].w=w;
    	e[edgeCnt].nxt=head[u];
    	head[u]=edgeCnt;
    }
    int n,dis[MAXN],cnt[MAXN];
    bool vis[MAXN];
    bool spfa(){
    	queue<int> q;
    	q.push(1);
    	dis[1]=0;
    	while(!q.empty()){
    		if(dis[q.front()]>dis[q.back()])swap(q.front(),q.back());
    		int u=q.front();q.pop();
    		vis[u]=0;
    		for(int i=head[u];i;i=e[i].nxt){
    			int nowV=e[i].to;
    			if(dis[nowV]>dis[u]+e[i].w){
    				dis[nowV]=dis[u]+e[i].w;
    				cnt[nowV]=cnt[u]+1;
    				if(cnt[nowV]>n)return 1;
    				if(!vis[nowV]){
    					vis[nowV]=1;
    					q.push(nowV);
    				}
    			}
    		}
    	}
    	return 0;
    }
    void init(){
    	memset(dis,0x3f,sizeof(dis));
    	memset(cnt,0,sizeof(cnt));
    	memset(vis,0,sizeof(vis));
    	memset(head,0,sizeof(head));//
    	edgeCnt=2;
    }
    int main(){
    	int t;
    	scanf("%d",&t);
    	while(t--){
    		init();
    		int m;
    		scanf("%d%d",&n,&m);
    		for(int i=1;i<=m;i++){
    			int a,b,w;
    			scanf("%d%d%d",&a,&b,&w);
    			addEdge(a,b,w);
    			if(w>=0)addEdge(b,a,w);
    		}
    		cout<<(spfa()?"YE5":"N0")<<endl;
    	}
    	return 0;
    }
  • 相关阅读:
    C# 抽象方法和虚方法的区别
    xmlhttprequest readyState 属性的五种状态
    ServiceStack破解文件
    k8s部署mysql
    docker 开放2376端口的问题
    .net core 发布到IIS 没有 web.config 文件
    1064
    docker mysql 主从同步配置
    Docker 鼠标在虚拟机与主机之间自由切换
    Socket原理解析2
  • 原文地址:https://www.cnblogs.com/zbsy-wwx/p/11680566.html
Copyright © 2020-2023  润新知