題目連接c++
判斷一張圖中是否存在關於頂點1的負環:數組
能夠用SPFA跑一遍,存在負環的狀況就是點進隊大於n次spa
由於在存在負環的狀況下,SPFA會越跑越小,跑進死循環code
在最差的狀況下,存在的負環長度是「n+1個頂點」這麼長blog
rt:get
顯然這是n個點長度,但不是環;it
這就是一個環,n+1個點的長度;io
因此代碼很明瞭了,只需將通常SPFA改動一點飢渴
CODE:class
#include<bits/stdc++.h>萬能頭,懶得打不少頭文件 using namespace std; //數據是騙人的,要開大.. const int maxn=50001; //基本的變量或者數組都是: queue<int > q; bool visited[maxn]; int head[maxn],cnt,js[maxn],dis[maxn]; struct ppap { int next,to,dis; } edge[maxn]; int t,n,m; //快讀部分 int read() { bool f=0; char ch; int x=0; ch=getchar(); while(ch>'9'||ch<'0') { if(ch=='-') f=!f; ch=getchar(); } while(ch<='9'&&ch>='0') { x=x*10+ch-'0'; ch=getchar(); } return !f?x:-x; } //鏈式前向星添邊 void add(int from,int to,int dis) { edge[++cnt].next=head[from]; head[from]=cnt; edge[cnt].to=to; edge[cnt].dis=dis; } //和常見spfa同樣,在其中判斷條件便可 bool SPFA() { q.push(1); visited[1]=1; dis[1]=0; js[1]=1; while(!q.empty()) { int u=q.front(); q.pop(); visited[u]=0; for(int i=head[u]; i; i=edge[i].next) { int v=edge[i].to; if(dis[v]>dis[u]+edge[i].dis) { dis[v]=dis[u]+edge[i].dis; if(visited[v]==0) { js[v]=js[u]+1; if(js[v]>n) return true; visited[v]=1; q.push(v); } } } } return false; } int main() { t=read(); while(t--) { n=read(),m=read(); memset(head,0,sizeof head); memset(js,0,sizeof js); memset(edge,0,sizeof edge); memset(dis,0x3f,sizeof dis); memset(visited,0,sizeof visited); //初始化 for(int i=1,a,b,w; i<=m; i++) { a=read(),b=read(),w=read(); add(a,b,w); if(w>=0) add(b,a,w); } if(SPFA()) cout<<"YE5"<<"\n"; else cout<<"N0"<<"\n"; } return 0;//平淡的結束 }
評測記錄變量