洛谷P2656 采蘑菇
\(\large{题目链接}\)
\(\\\)
\(\Large\textbf{Solution: } \large{缩点+\text{Spfa},细节较多,咕咕咕。}\)
\(\\\)
\(\Large\textbf{Code: }\)
#include <bits/stdc++.h>
using namespace std;
typedef double dl;
const int N = 8e4 + 5;
const int M = 2e5 + 5;
const int inf = 0x7fffffff;
int s, m, n, cnt, head[M];
int tot, top, sta[N], low[N], dfn[N], vis[N];
int cot, bel[N], h[N], deg[N], num[N];
int Max, dis[N];
struct Edge {
int to, next, fr, val;
dl r;
}e[M];
struct EDGE {
int to, next, val;
}E[M];
int read() {
int x = 0, flg = 1;
char ch = getchar();
while (!isdigit(ch)) {
if (ch == '-') flg = -1;
ch = getchar();
}
while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
return x * flg;
}
void add(int x, int y, int w, dl r) {
e[++cnt].to = y;
e[cnt].fr = x;
e[cnt].val = w;
e[cnt].r = r;
e[cnt].next = head[x];
head[x] = cnt;
}
void Add(int x, int y, int w) {
E[++cnt].to = y;
E[cnt].val = w;
E[cnt].next = h[x];
h[x] = cnt;
}
void calc(int x, int w, dl r) {
while (w) {
deg[x] += w;
w = floor((dl)w * r);
}
}
void Tarjan(int x) {
low[x] = dfn[x] = ++tot;
sta[++top] = x, vis[x] = 1;
for (int i = head[x]; i ; i = e[i].next) {
int u = e[i].to;
if (!dfn[u]) Tarjan(u), low[x] = min(low[x], low[u]);
else if (vis[u]) low[x] = min(low[x], dfn[u]);
}
if (low[x] == dfn[x]) {
int cur, xx = top; ++cot;
while (top) {
cur = sta[top--];
vis[cur] = 0;
bel[cur] = cot;
if (cur == x) break;
}
}
}
void Spfa() {
memset(dis, -1, sizeof (dis)); memset(vis, 0, sizeof (vis));
Max = dis[s] = deg[s];
queue <int> q; q.push(s), vis[s] = 1;
while (!q.empty()) {
int x = q.front(); q.pop();
vis[x] = 0;
for (int i = h[x]; i ; i = E[i].next) {
int u = E[i].to;
if (dis[u] < dis[x] + deg[u] + E[i].val) {
dis[u] = dis[x] + deg[u] + E[i].val;
Max = max(Max, dis[u]);
if (!vis[u]) vis[u] = 1, q.push(u);
}
}
}
}
int main() {
n = read(), m = read();
int x, y, w; dl r;
while (m--) x = read(), y = read(), w = read(), scanf("%lf", &r), add(x, y, w, r);
s = read(); Tarjan(s); s = bel[s];
int k = cnt; cnt = 0;
for (int i = 1; i <= k; ++i) {
int u = bel[e[i].fr], v = bel[e[i].to];
if (u != v) Add(u, v, e[i].val);
else calc(v, e[i].val, e[i].r);
}
Spfa();
printf("%d\n", Max);
return 0;
}