题目链接: http://poj.org/problem?id=3259
题意: 现农民John有一个农场,这个农场有 n 个区域,m条道路 。 他发现在农场有 w 个虫洞, 这些虫洞有神奇的作用, 可以带人穿越时空, 问你是否可以通过给定的一些道路以及虫洞, 人可以回到出发的位置看到还未出发的自己? (负权边)
spfa算法
#include <iostream> #include <cstdio> #include <cstring> #include <stdlib.h> #include <math.h> #include <queue> #include <algorithm> using namespace std; #define maxn 5210 #define INF 0xfffffff int head[maxn],dist[maxn],v[maxn],num[maxn]; int cnt, n; struct node { int v, w, next; } maps[maxn]; void Add(int u, int v, int w) { maps[cnt].v = v; maps[cnt].w = w; maps[cnt].next = head[u]; head[u] = cnt++; } int spfa() { memset(num, 0, sizeof(num)); memset(v, 0, sizeof(v)); queue<int>Q; Q.push(1); num[1]++; while(Q.size()) { int p = Q.front(); Q.pop(); v[p] = 0; for(int i=head[p]; i!=-1; i=maps[i].next) { int q = maps[i].v; if(dist[q] > dist[p] + maps[i].w) { dist[q] = dist[p] + maps[i].w; if(!v[q]) { v[q]=1; num[q]++; Q.push(q); if(num[q] > n) return 1; } } } } return 0; } int main() { int t, m, w, a, b, c; scanf("%d", &t); while(t --) { scanf("%d %d %d", &n, &m, &w); dist[1] = 0; for(int i=2; i<=n; i++) dist[i] = INF; cnt = 0; memset(head, -1, sizeof(head)); while(m --) { scanf("%d %d %d", &a, &b, &c); Add(a, b, c); Add(b, a, c); } while(w --) { scanf("%d %d %d", &a, &b, &c); Add(a, b, -c); } int ans = spfa(); if(ans) printf("YES "); else printf("NO "); } return 0; }