luogu3385 负环 (spfa)

我在做spfa的时候,如果有一个点被更新了超过N次,证明这个图里是有负环的。

(神TM输出YE5和N0

 1 #include<bits/stdc++.h>
 2 #define pa pair<int,int>
 3 #define CLR(a,x) memset(a,x,sizeof(a))
 4 using namespace std;
 5 typedef long long ll;
 6 const int maxn=2020,maxm=3030;
 7 
 8 inline ll rd(){
 9     ll x=0;char c=getchar();int neg=1;
10     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
11     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
12     return x*neg;
13 }
14 
15 struct Edge{
16     int a,b,l,ne;
17 }eg[maxm*2];
18 int egh[maxn],ect;
19 int N,M;
20 int cnt[maxn],dis[maxn];
21 queue<int> q;
22 bool inq[maxn];
23 
24 inline void adeg(int a,int b,int l){
25     eg[++ect].a=a;eg[ect].b=b;eg[ect].l=l;eg[ect].ne=egh[a];egh[a]=ect;
26 }
27 
28 bool spfa(int s){
29     
30     while(!q.empty()) q.pop();
31     dis[s]=0;q.push(s);cnt[s]=1;
32     while(!q.empty()){
33         int p=q.front();inq[p]=0;
34         // printf("%d %d\n",p,dis[p]);
35         q.pop();
36         for(int i=egh[p];i;i=eg[i].ne){
37             int b=eg[i].b;
38             if(dis[b]>dis[p]+eg[i].l){
39                 dis[b]=dis[p]+eg[i].l;
40                 if(inq[b]) continue;
41                 if(++cnt[b]>N) return 1;
42                 q.push(b);
43                 inq[b]=1;
44             }
45         }
46     }return 0;
47 }
48 
49 int main(){
50     //freopen("","r",stdin);
51     int i,j,k;
52     for(int T=rd();T;T--){
53         ect=0;CLR(egh,0);
54         N=rd(),M=rd();
55         for(i=1;i<=M;i++){
56             int a=rd(),b=rd(),c=rd();
57             adeg(a,b,c);
58             if(c>=0) adeg(b,a,c);
59         }
60         bool ans=0;
61         CLR(cnt,0);CLR(dis,127);CLR(inq,0);
62         for(i=1;i<=N&&!ans;i++){
63             if(!cnt[i]) ans|=spfa(i);
64         }
65         if(ans) printf("YE5\n");
66         else printf("N0\n");
67     }
68     return 0;
69 }

 

posted @ 2018-10-13 10:35  Ressed  阅读(167)  评论(0编辑  收藏  举报