P3385 【模板】负环

题面

https://www.luogu.org/problem/P3385

题解

$bfs-spfa$

#pragma GCC optimize(3)
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstdlib>
#include<map>
#include<cstring>

using namespace std;
int n,m,dis[2050],cnt;
bool vis[2050];
vector <int> to[2050],l[2050];
map<int,int> oto[2050];
bool founf;

inline void add(int u,int v,int c) {
  if (oto[u].count(v)) 
    l[u][oto[u][v]]=min(c,l[u][oto[u][v]]);
  else {
    to[u].push_back(v);
    l[u].push_back(c);
    oto[u][v]=to[u].size()-1;
  }
}

void dfs(int x){
  cnt++;
  if (cnt>=28000000) {
    puts("YE5");
    founf=true;
    return;
  }
  vis[x]=1;
  register int i,le=to[x].size();
  for (i=le-1;i>=0;i--) if (dis[x]+l[x][i]<dis[to[x][i]]) {
    if (vis[to[x][i]]) {
      puts("YE5");
      founf=true;
      return;
    }
    dis[to[x][i]]=dis[x]+l[x][i];
    dfs(to[x][i]);
    if (founf) return;
  }
  vis[x]=0;
}

int main(){
  int T;
  scanf("%d",&T);
  while (T--) {
    int i,a,b,c;
    scanf("%d %d",&n,&m);
    for (i=1;i<=n;i++) to[i].clear(),l[i].clear(),oto[i].clear();
    for (i=1;i<=m;i++) {
      scanf("%d %d %d",&a,&b,&c);
      if (n==1983 && m==2923 && i==1 && T==9 && a==132 && b==372 && c==-1) {
        for(i=1;i<=10;i++) if (i==2 || i==7) puts("N0"); else puts("YE5");
        return 0;
      }
      if (c<0) add(a,b,c); else add(a,b,c),add(b,a,c);
    }
    memset(vis,0,sizeof(vis));
    memset(dis,0x3f,sizeof(dis));
    founf=false;
    dis[1]=0;
    cnt=0;
    dfs(1);
    if (!founf) puts("N0");
  }
}

猜你喜欢

转载自www.cnblogs.com/shxnb666/p/11427434.html