洛谷P2656 采蘑菇

\(\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;
} 

猜你喜欢

转载自www.cnblogs.com/Miraclys/p/12605629.html