最短路题目

负环 https://www.luogu.com.cn/problem/P3385

  • 使用BFS的SPFA算法和普通的SPFA没有什么区别,我们如何判断有没有负环呢?我们有两种判法.

  • 1.记录此点被更新了多少次,更新次数大于N就有负环.这意味着一个点被重复迭代超过N次,显然有负环.

  • 2.记录从S到当前点路径上经过了多少个点,超过N则有负环.这张图才有N个点,一条路径上没有重复点经过点数是<= N的,所以有负环.

用 t[ ] 表示被迭代多少次

 1 #include<iostream>
 2 #include<queue>
 3 #include<cstring>
 4 
 5 #define M 6010
 6 #define N 2010
 7 #define clear(a) memset(a,0,sizeof(a))
 8 
 9 using namespace std;
10 
11 int dis[N],t[N];
12 bool vis[N];
13 int n,m,x,y,z,tot;
14 int hd[M];
15 struct node{
16     int ver,nxt,w;
17 }e[M];
18 queue<int> q;
19 
20 void add(int x,int y,int z){
21     e[++tot].ver=y,e[tot].w=z,e[tot].nxt=hd[x],hd[x]=tot;
22 }
23 
24 bool spfa(){
25     memset(dis,0x3f,sizeof(dis));
26     memset(vis,false,sizeof(vis));
27     memset(t,0,sizeof(t));
28     while(!q.empty()) q.pop();
29     dis[1]=0;vis[1]=1;t[1]=1;
30     q.push(1);
31     while(q.size()){
32         int x=q.front();q.pop();
33         vis[x]=0;
34         for(int i=hd[x];i;i=e[i].nxt){
35             int y=e[i].ver,z=e[i].w;
36             if(dis[y]>dis[x]+z){
37                 dis[y]=dis[x]+z;
38                 if(++t[y]>n) return 1;
39                 if(!vis[y]) q.push(y),vis[y]=1;
40             }
41         }
42     }
43     return 0;
44 }
45 
46 int main()
47 {
48     int T;
49     cin>>T;
50     while(T--)
51     {
52         tot=0;memset(hd,0,sizeof(hd));
53         cin>>n>>m;
54         for(int i=1;i<=m;i++)
55         {
56             cin>>x>>y>>z;
57             if(z<0)  add(x,y,z);
58             else  add(x,y,z),add(y,x,z);
59         }
60         if(spfa())  cout<<"YE5"<<endl;//坑!!!
61         else  cout<<"N0"<<endl;
62     }
63     return 0;
64 }

 

上一篇:关于$memset$


下一篇:LightOJ - 1422——(区间DP)