普通的SPFA:
int top; int head[MAXN]; struct Edge { int v, nxt; int w; } edge[MAXM]; void init() { top = 0; memset(head, -1, sizeof(head)); } void add_edge(int u, int v, int w) { ++top; edge[top].v = v; edge[top].w = w; edge[top].nxt = head[u]; head[u] = top; } bool vis[MAXN]; int cnt[MAXN]; int dis[MAXN]; queue<int>q; bool spfa(int s, int n) { memset(vis, 0, sizeof(vis)); memset(cnt, 0, sizeof(cnt)); for(int i = 0; i < MAXN; ++i) dis[i] = 0x3f3f3f3f; while(!q.empty()) q.pop(); q.push(s); vis[s] = 1; cnt[s] = 1; dis[s] = 0; while(!q.empty()) { int u = q.front(); q.pop(); vis[u] = 0; for(int i = head[u]; i != -1; i = edge[i].nxt) { int v = edge[i].v; if(dis[v] > dis[u] + edge[i].w) { dis[v] = dis[u] + edge[i].w; if(!vis[v]) { vis[v] = 1; q.push(v); if(++cnt[v] > n) return 0; } } } } return 1; }
带SLF优化的SPFA,实测在某些数据上确实会快(有人说是15%左右,但实际上貌似不止?反正抖得厉害)
int top; int head[MAXN]; struct Edge { int v, nxt; int w; } edge[MAXM]; void init() { top = 0; memset(head, -1, sizeof(head)); } void add_edge(int u, int v, int w) { ++top; edge[top].v = v; edge[top].w = w; edge[top].nxt = head[u]; head[u] = top; } bool vis[MAXN]; int cnt[MAXN]; int dis[MAXN]; deque<int>q; bool spfa(int s, int n) { memset(vis, 0, sizeof(vis)); memset(cnt, 0, sizeof(cnt)); for(int i = 0; i < MAXN; ++i) dis[i] = 0x3f3f3f3f; q.clear(); q.push_back(s); vis[s] = 1; cnt[s] = 1; dis[s] = 0; while(!q.empty()) { int u = q.front(); q.pop_front(); vis[u] = 0; for(int i = head[u]; i != -1; i = edge[i].nxt) { int v = edge[i].v; if(dis[v] > dis[u] + edge[i].w) { dis[v] = dis[u] + edge[i].w; if(!vis[v]) { vis[v] = 1; //SLF优化 据说15%~20% if(!q.empty() && dis[v] >= dis[q.front()]) q.push_back(v); else q.push_front(v); if(++cnt[v] > n) return 0; } } } } return 1; }