求助
  • 板块灌水区
  • 楼主buowen123
  • 当前回复1
  • 已保存回复1
  • 发布时间2023/11/12 20:47
  • 上次更新2023/11/12 22:13:06
查看原帖
求助
752017
buowen123楼主2023/11/12 20:47

这份代码 GFOJ 上 50 分,求调

圣诞老人准备在圣诞节给 ACMer 送礼物,每个 ACMer 都有一个寝室,寝室之间有单向道路。每个人对于圣诞老人发的礼物都有一个心情值的影响。圣诞老人每到达一个寝室可以进去发礼物也可以不发,可以到达一个寝室多次,不能给一个寝室发多个礼物,求心情影响值之和最大值。

#include <iostream>
using namespace std;
typedef long long ll;
const int N = 3e4 + 5, M = 1.5e5 + 5;
int n, m, tot1, tot2, head1[N], head2[N];
int cnt, top, scnt, dfn[N], low[N], stk[N], p[N];
bool instk[N], vis[N];
ll ans, a[N], w[N], dp[N];


struct edge {
	int to, nxt;
} e1[M], e2[M];

void add1 (int u, int v) {
	++tot1;
	e1[tot1].nxt = head1[u];
	e1[tot1].to = v;
	head1[u] = tot1;
}

void add2 (int u, int v) {
	++tot2;
	e2[tot2].nxt = head2[u];
	e2[tot2].to = v;
	head2[u] = tot2;
}

void tarjan (int u) {
	++cnt;
	++top;
	dfn[u] = cnt;
	low[u] = cnt;
	stk[top] = u;
	instk[u] = true;
	vis[u] = true;
	for (int i = head1[u]; i; i = e1[i].nxt) {
		int v = e1[i].to;
		if (vis[v] == false) {
			tarjan (v);
			low[u] = min (low[u], low[v]);
		} 
		if (vis[v] == true && instk[i] == true) {
			low[u] = min (low[u], dfn[v]);
		}
	}
	if (dfn[u] == low[u]) {
		++scnt;
		int tmp = 0;
		do {
			tmp = stk[top];
			instk[tmp] = false;
			p[tmp] = scnt;
			w[scnt] += a[tmp];
			--top;
		} while (tmp != u);
	}
}

ll dfs (int u) {
	if (dp[u] != 0) {
		return dp[u];
	}
	for (int i = head2[u]; i; i = e2[i].nxt) {
		int v = e2[i].to;
		ll qwq = dfs (v);
		if (dp[u] < qwq) {
			dp[u] = qwq;
		}
	}
	dp[u] += w[u];
	return dp[u];
}

int main () {
	scanf ("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf ("%lld", &a[i]);
	}
	for (int i = 1; i <= n; ++i) {
		if (a[i] < 0) {
			a[i] = 0;
		}
	}
	for (int i = 1; i <= m; ++i) {
		int u, v;
		cin >> u >> v;
		add1 (u + 1, v + 1);//题目的输入从 0 编号,不用管
	}
	for (int i = 1; i <= n; ++i) {
		if (vis[i] == false) {
			tarjan (i);
		}
	}
	for (int u = 1; u <= n; ++u) {
		for (int i = head1[u]; i; i = e1[i].nxt) {
			int v = e1[i].to;
			if (p[u] != p[v]) {
				add2 (p[v], p[u]);
			}
		}
	}
	for (int i = 1; i <= scnt; ++i)
	{
		if (dp[i] == 0) {
			dfs (i);
		}
		if (ans < dp[i]) {
			ans = dp[i];
		}
	}
	printf ("%lld", ans);
	return 0;
}
2023/11/12 20:47
加载中...