spfa负环判断(DFS+BFS两种)

背景

给定一个图,判断有无负环


虽然spfa很不稳定_(:з」∠)_ ,但在处理含负权值最短路时为首选(特别是差分约束系统)

而部分题目额外要求判断有无负环(即最短路为-\infty)

下面给出由BFS(最短路算法一般基于bfs),与DFS(一般用于处理环)两种不同的同时计算最短路与寻找负环的思路

 

BFS:基于Bellman-Ford算法,通过判断一个点relax()操作,是否进行次数\geq N(即走了至少N个点)

由于BFS处理环能力较弱,故该判断方法若遇到负环很可能TLE

bool spfa(int org){
  memset(dis, 60, sizeof(dis));
  int i;
  queue Q;
  dis[org] = 0, vis[org] = true, Q.push(org);
  while(!Q.empty()){
    int u = Q.front(); Q.pop();
    vis[u] = false;
    for(i = head[u]; i; i = e[i].next){
      int v = e[i].to, w = e[i].w;
      if(dis[v] > dis[u] + w){
        dis[v] = dis[u] + w;
        cnt[v] = cnt[u] + 1;
        if(cnt[v] == N + 1) return false;
        if(!vis[v]) Q.push(v), vis[v] = true;
      }
    }
  }
  return true;
}

 

DFS:dfs通过后向边即可以快速的判断环,如果一个relax()操作通过后向边则有负环(即最短路形成了一个环)

DFS处理最短路能力较若弱,一般针对负环的题目

PS:其实这已经已经不是spfa了,而是相当于针对环的Bellman-Ford

bool spfa(int u){
  vis[u] = true;
  int i;
  for(i = head[u]; i; i = e[i].next){
    int v = e[i].to, w = e[i].w;
    if(dis[v] > dis[u] + w){
      dis[v] = dis[u] + w;
      if(vis[v]) return false;
      if(!spfa(v)) return false;
    }
  }
  vis[u] = false;
  return true;
}

 

你可能感兴趣的:(图论-最短路问题)