1. 程式人生 > >洛谷P3385 【模板】負環

洛谷P3385 【模板】負環

題目描述

暴力列舉/SPFA/Bellman-ford/奇怪的貪心/超神搜尋

尋找一個從頂點1所能到達的負環,負環定義為:一個邊權之和為負的環。

輸入輸出格式

輸入格式:

第一行一個正整數T表示資料組數,對於每組資料:

第一行兩個正整數N M,表示圖有N個頂點,M條邊

接下來M行,每行三個整數a b w,表示a->b有一條權值為w的邊(若w<0則為單向,否則雙向)

輸出格式:

共T行。對於每組資料,存在負環則輸出一行"YE5"(不含引號),否則輸出一行"N0"(不含引號)。

輸入輸出樣例

輸入樣例#1: 
2
3 4
1 2 2
1 3 4
2 3 1
3 1 -3
3 3
1 2 3
2 3 4
3 1 -8
輸出樣例#1: 
N0
YE5

說明

n\leq 2000n2000m\leq 3000m3000-10000\leq w\leq 1000010000w10000T\leq 10T10建議複製輸出格式中的字串。 本題資料感謝@negiizhao的精心構造,請不要使用玄學演算法 本題資料有更新

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<queue>
  6
using namespace std; 7 long long read() 8 { 9 long long x=0,f=1; 10 char ch=getchar(); 11 while(ch>'9'||ch<'0') 12 { 13 if(ch=='-') 14 f=-1; 15 ch=getchar(); 16 } 17 while(ch>='0'&&ch<='9') 18 { 19 x=x*10
+ch-'0'; 20 ch=getchar(); 21 } 22 return x*f; 23 } 24 const int maxn=20005; 25 const int maxm=100010; 26 int T,st=1,n,m,num; 27 bool flag; 28 bool vis[maxn]; 29 int dis[maxn],cnt[maxn],head[maxn],q[maxn]; 30 struct node 31 { 32 int v,w,nxt; 33 } e[maxm*2]; 34 void add(int x,int y,int z) 35 { 36 e[++num].v=y; 37 e[num].w=z; 38 e[num].nxt=head[x]; 39 head[x]=num; 40 } 41 bool spfa() 42 { 43 int l=0,r=0; 44 memset(dis,0x3f,sizeof(dis)); 45 memset(vis,0,sizeof(vis)); 46 memset(cnt,0,sizeof(cnt)); 47 memset(q,0,sizeof(q)); 48 vis[st]=1; 49 cnt[st]=1; 50 dis[st]=0; 51 q[r++]=st; 52 while(l!=r) 53 { 54 int u=q[l++]; 55 if(l>n) 56 l=0; 57 vis[u]=false; 58 for(int i=head[u]; i; i=e[i].nxt) 59 { 60 if(dis[e[i].v]>dis[u]+e[i].w) 61 { 62 dis[e[i].v]=dis[u]+e[i].w; 63 cnt[e[i].v]=cnt[u]+1; 64 if(cnt[e[i].v]>=n&&e[i].w<0) 65 return 1; 66 if(!vis[e[i].v]) 67 { 68 vis[e[i].v]=1; 69 if(dis[e[i].v]>dis[q[l]]) 70 { 71 l--; 72 if(l<0) 73 l=n; 74 q[l]=e[i].v; 75 } 76 else 77 { 78 q[r++]=e[i].v; 79 if(r>n) 80 r=0; 81 } 82 } 83 } 84 } 85 } 86 return false; 87 } 88 int main() 89 { 90 T=read(); 91 while(T--) 92 { 93 n=read(),m=read(); 94 memset(head,0,sizeof(head)); 95 num=0; 96 for(int i=1; i<=m; i++) 97 { 98 int x=read(),y=read(),w=read(); 99 add(x,y,w); 100 if(w>=0) 101 add(y,x,w); 102 } 103 if(spfa()) 104 printf("YE5\n"); 105 else 106 printf("N0\n"); 107 } 108 return 0; 109 }
View Code