洛谷P1938 [USACO09NOV]Job Hunt S
\(\large{题目链接}\)
\(\\\)
\(\Large\textbf{Solution: } \large{对于题目中的飞机与道路,可以当作边权为负与零的一条边。\\由于每到一个城市能获得D的收益,那么可以给每条边的边权再加一个D,最后Spfa跑最长路顺便判环即可。}\)
\(\\\)
\(\Large\textbf{Code: }\)
#include <bits/stdc++.h>
#define gc() getchar()
#define LL long long
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define _rep(i, a, b) for (int i = (a); i >= (b); --i)
using namespace std;
const int N = 225;
const int inf = 0x7fffffff;
int n, m1, m2, s, cnt, val, ans, head[N], vis[N], r[N], c[N];
struct Edge {
int to, next, val;
}e[N << 1];
inline int read() {
int x = 0;
char ch = gc();
while (!isdigit(ch)) ch = gc();
while (isdigit(ch)) x = x * 10 + ch - '0', ch = gc();
return x;
}
inline void add(int x, int y, int w) {
e[++cnt].to = y;
e[cnt].next = head[x];
e[cnt].val = w;
head[x] = cnt;
}
inline bool Spfa() {
queue<int> q;
rep(i, 1, n) c[i] = -inf;
c[s] = ans = val, r[1] = 0; q.push(1);
while (!q.empty()) {
int x = q.front(); q.pop();
vis[x] = 0;
for (int i = head[x]; i ; i = e[i].next) {
int u = e[i].to;
if (c[u] < c[x] + e[i].val) {
c[u] = c[x] + e[i].val;
ans = max(ans, c[u]);
if (!vis[u]) vis[u] = 1, q.push(u);
if (++r[u] > n) return false;
}
}
}
return true;
}
int main() {
val = read(), m1 = read(), n = read(), m2 = read(), s = read();
int x, y, w;
while (m1--) x = read(), y = read(), add(x, y, val);
while (m2--) x = read(), y = read(), w = read(), add(x, y, val - w);
int flg = Spfa();
if (flg) cout << ans << endl;
else cout << "-1" << endl;
return 0;
}