POJ 3259 Wormholes SPFA算法题解

来源:互联网 发布:阿里云创建自定义镜像 编辑:程序博客网 时间:2024/06/15 15:21

本题其实也可以使用SPFA算法来求解的,不过就一个关键点,就是当某个顶点入列的次数超过所有顶点的总数的时候,就可以判断是有负环出现了。

SPFA原来也是可以处理负环的。

不过SPFA这种处理负环的方法自然比一般的Bellman Ford算法要慢点了。

#include <stdio.h>#include <string.h>#include <limits.h>const int MAX_N = 501;const int MAX_M = 2501;const int MAX_W = 201;struct Edge{int src, des, wei, next;//Edge(int s, int d, int w) : src(s), des(d), wei(w) {}};Edge edge[(MAX_M<<1)+MAX_W];int dist[MAX_N];int head[MAX_N];bool vis[MAX_N];int qu[MAX_N];int cnt[MAX_N];int totalEdges;inline void insertEdge(int src, int des, int wei){edge[totalEdges].src = src, edge[totalEdges].des = des;edge[totalEdges].wei = wei; edge[totalEdges].next = head[src];head[src] = totalEdges++;}int N, M, W, F;bool cycleSPFA(){for (int i = 1; i <= N; i++) dist[i] = INT_MAX;dist[1] = 0;memset(vis, 0, sizeof(bool)*(N+1));memset(cnt, 0, sizeof(int)*(N+1));int top = 0, tail = 1;//循环队列的头和尾下标qu[top] = 1;vis[1] = true;cnt[1] = 1;while (top < tail){int u = qu[top%MAX_N];//自定义循环队列top++;vis[u] = false;for (int e = head[u]; e ; e = edge[e].next){int v = edge[e].des;if (dist[u]+edge[e].wei < dist[v]){dist[v] = dist[u]+edge[e].wei;if (!vis[v]){vis[v] = true;qu[tail%MAX_N] = v;tail++;cnt[v]++;//记录入列次数if (cnt[v] >= N) return true;}}}}return false;}int main(){int src, des, wei;scanf("%d", &F);while (F--){scanf("%d %d %d", &N, &M, &W);memset(head, 0, sizeof(int) * (N+1));totalEdges = 1;for (int i = 0; i < M; i++){scanf("%d %d %d", &src, &des, &wei);insertEdge(src, des, wei);insertEdge(des, src, wei);}for (int i = 0; i < W; i++){scanf("%d %d %d", &src, &des, &wei);insertEdge(src, des, -wei);}if (cycleSPFA()) puts("YES");else puts("NO");}return 0;}


1 0
原创粉丝点击