负环

负环

什么是负环

顾名思义 就是一个所有边的边权和为负数的环

出现负环会怎么样

一旦出现负环,那么s到t的最短路就会不断地走这个环。那么每条最短路每经过一次负环,最短路就会减少一点。

如果走无数次,那么也就不存在最短路。当然每个点经过的次数不超过1

怎么判负环

这里我们讲比较常用的SPFA判负环(虽然SPFA他死了)。如果存在负环,那么最短路就会不断地缩小。我们可以利用

这个特性 在SPFA中每个点最多被其他n-1个点更新一次。如果被更新了n次,那么说明存在负环。

模板——>负环

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<queue>
 5 #include<cstring>
 6 using namespace std;
 7 int t,n,m,tot,u,v,w;
 8 int head[2100],dis[2100],num[2100];
 9 bool in[2100];
10 struct node{
11     int to;
12     int w;
13     int net;
14 }e[6100];
15 void add(int x,int y,int w){
16     tot++;
17     e[tot].to = y;
18     e[tot].w = w;
19     e[tot].net = head[x];
20     head[x] = tot;
21 }
22 bool spfa(){
23     memset(dis,0x7f,sizeof(dis));
24     memset(in,0,sizeof(in));
25     memset(num,0,sizeof(num));
26     queue<int> q;
27     q.push(1); dis[1] = 0;
28     num[1] = 1,in[1] = 1;
29     while(!q.empty()){
30         int t = q.front();
31         q.pop();
32         in[t] = 0;
33         for(int i = head[t]; i; i = e[i].net){
34             int to = e[i].to;
35             if(dis[to] > dis[t] + e[i].w){
36                 dis[to] = dis[t] + e[i].w;
37                 num[to]++;
38                 if(num[to] > n) return 1;
39                 if(in[to] == 0){
40                     q.push(to);
41                     in[to] = 1;
42                 }
43             }
44         }
45     }
46     return 0;
47 } 
48 int main(){
49     scanf("%d",&t);
50 while(t--){ 51 scanf("%d%d",&n,&m); 52 tot = 0; 53 memset(head,0,sizeof(head)); 54 for(int i = 1; i <= m; i++){ 55 scanf("%d%d%d",&u,&v,&w);
56 if(w >= 0){ 57 add(u,v,w); 58 add(v,u,w); 59 } 60 else add(u,v,w); 61 } 62 if(spfa()) cout<<"YE5"<<endl; 63 else cout<<"N0"<<endl; 64 } 65 }

习题    虫洞  

          方伯伯运椰子

         

posted @ 2020-07-12 16:07  genshy  阅读(470)  评论(0编辑  收藏  举报