afasf,令T[i] = a1+a2+....ai;
则Si = a[Si]+a[Si+1]+...a[Si+ni] = T[Si+ni]-T[Si-1];
以T[i]为节点,i的范围为0<=i<=n,然后根据题目条件加上约束条件,然后判断正/负均可。
#include <iostream> #include <cstdlib> #include <cstdio> #include <string> #include <cstring> #include <cmath> #include <vector> #include <queue> #include <algorithm> #include <map> #include <stack> using namespace std; const int maxn = 2010 + 10; const int INF = 0x3f3f3f3f; struct Edge { int from, to, dist; Edge(int from, int to, int dist): from(from), to(to), dist(dist) {} }; struct SPFA { int n, m; vector<int> G[maxn]; vector<Edge> edges; bool inq[maxn]; int d[maxn]; int p[maxn]; int cnt[maxn]; void init(int n) { this->n = n; for(int i = 0; i <= n; i++) G[i].clear(); edges.clear(); } void AddEdge(int from, int to, int dist) { edges.push_back(Edge (from, to, dist)); m = edges.size(); G[from].push_back(m-1); } bool spfa(int s) { queue<int> Q; memset(inq, 0, sizeof(inq)); memset(cnt, 0, sizeof(cnt)); for(int i = 0; i <= n; i++) { inq[s] = 1; Q.push(i); d[i] = 0; } while(!Q.empty()) { int u = Q.front(); Q.pop(); inq[u] = 0; for(int i = 0; i < G[u].size(); i++) { Edge &e = edges[G[u][i]]; if(d[e.to] < d[u] + e.dist) { d[e.to] = d[u]+e.dist; p[e.to] = G[u][i]; if(!inq[e.to]) { Q.push(e.to); inq[e.to] = 1; if(++cnt[e.to] > n) return 1; } } } } return 0; } }; /////////////////// SPFA g; int n, m; //////// T[i]的范围是0~n; int main() { while(~scanf("%d%d", &n, &m) && n) { g.init(n+10); int SI, NI, KI; char cmd[9]; for(int i = 1; i <= m; i++) { scanf("%d%d%s%d", &SI, &NI, cmd, &KI); if(cmd[0] == 'g') g.AddEdge(SI-1, SI+NI, KI+1); else if(cmd[0] == 'l') g.AddEdge(SI+NI, SI-1, -(KI-1)); } if(!g.spfa(0)) printf("lamentable kingdom\n"); else printf("successful conspiracy\n"); } return 0; }