spfa求最长路
http://poj.org/problem?id=1932
spfa求最长路,判断dist[n] > 0,需要注意的是有正环存在,如果有环存在,那么就要判断这个环上的某一点是否能够到达n点,如果能,就说明可以到达,否则,就说明不能。
1 /************************************************************************* 2 > File Name: poj1932.cpp 3 > Author: syhjh 4 > Created Time: 2014年03月04日 星期二 16时54分43秒 5 ************************************************************************/ 6 #include <iostream> 7 #include <cstdio> 8 #include <cstring> 9 #include <algorithm> 10 #include <vector> 11 #include <queue> 12 using namespace std; 13 14 const int MAXN = (100 + 10); 15 const int inf = 0x3f3f3f3f; 16 int n, st, energy[MAXN]; 17 int dp[MAXN], Count[MAXN]; 18 vector<int > g[MAXN]; 19 bool mark[MAXN]; 20 21 bool spfa() 22 { 23 for (int i = 1; i <= n; i++) dp[i] = -inf; 24 memset(mark, false, sizeof(mark)); 25 memset(Count, 0, sizeof(Count)); 26 queue<int > que; 27 que.push(1); 28 dp[1] = 100; 29 while (!que.empty()) { 30 int u = que.front(); 31 que.pop(); 32 mark[u] = false; 33 if (Count[u]++ > n || u == n) { 34 st = u; 35 return true; 36 } 37 for (int i = 0; i < (int)g[u].size(); i++) { 38 int v = g[u][i]; 39 if (dp[u] + energy[v] > dp[v] && dp[u] + energy[v] > 0) { 40 dp[v] = dp[u] + energy[v]; 41 if (!mark[v]) { 42 mark[v] = true; 43 que.push(v); 44 } 45 } 46 } 47 } 48 return false; 49 } 50 51 void dfs(int u) 52 { 53 mark[u] = true; 54 for (int i = 0; i < (int)g[u].size(); i++) { 55 int v = g[u][i]; 56 if (!mark[v]) dfs(v); 57 } 58 } 59 60 61 int main() 62 { 63 while (cin >> n && n != -1) { 64 for (int i = 1; i <= n; i++) g[i].clear(); 65 for (int i = 1; i <= n; i++) { 66 int u, k; 67 cin >> energy[i] >> k; 68 while (k--) { 69 cin >> u; 70 g[i].push_back(u); 71 } 72 } 73 st = -1; 74 if (spfa()) { 75 memset(mark, false, sizeof(mark)); 76 dfs(st); 77 if (mark[n]) { 78 cout << "winnable" << endl; 79 } else 80 cout << "hopeless" << endl; 81 } else if (dp[n] > 0) { 82 cout << "winnable" << endl; 83 } else 84 cout << "hopeless" << endl; 85 } 86 return 0; 87 }