Codeforces Round 660 (Div. 2) D. Captain Flint and Treasure(图论建模,拓扑排序)

题目链接

Codeforces Round 660 (Div. 2) D. Captain Flint and Treasure

思路

对于第 i i i个数,如果 b i ≠ − 1 b_{i} \ne -1 bi=−1,则第 i i i个数的值 a i a_{i} ai就可以叠加到第 b i b_{i} bi个数上。

因此,如果当前 a i a_{i} ai的值是大于等于 0 0 0的,则下一个选择第 b i b_{i} bi个数对答案产生的贡献就是最优的。如果 a i a_{i} ai的值是小于 0 0 0的,可以将其放到排列的后面。

每一个 i i i都只对应一个 b i b_{i} bi,而题目规定 b i , b b i , b b b i , . . . . . . b_{i},b_{b_{i}},b_{b_{b_{i}}},...... bi,bbi,bbbi,......都不是循环的。因此我们可以从 i i i向 b i b_{i} bi连一条有向边,最后形成的图一定是一个拓扑图。

因此我们可以使用拓扑排序直接计算最终的排列,对于 a i < 0 a_{i} < 0 ai<0的点,我们可以将其放入一个栈中,在最后统计到排列里。

代码

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;
const int N = 2e5 + 5, M = 1e4 + 5;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f3f3f3f3f;

int n, ans;
int a[N], b[N], du[N];
bool st[N];
vector<int>dfn, tmp;
vector<int>mp[N];
void topsort()
{
	queue<int>q;
	for (int i = 1; i <= n; i++)
	{
		if (!du[i])
		{
			q.push(i);
		}
	}
	while (q.size())
	{
		int u = q.front();
		ans += a[u];
		q.pop();
		if (a[u] >= 0) dfn.push_back(u);
		else tmp.push_back(u);
		for (int j : mp[u])
		{
			if (a[u] >= 0) a[j] += a[u];
			du[j]--;
			if (du[j] == 0)
			{
				q.push(j);
			}
		}
	}
}
void solve()
{
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		cin >> a[i];
	}
	for (int i = 1; i <= n; i++)
	{
		cin >> b[i];
	}
	for (int i = 1; i <= n; i++)
	{
		if (b[i] != -1)
		{
			mp[i].push_back(b[i]);
			du[b[i]]++;
		}
	}
	topsort();
	reverse(tmp.begin(), tmp.end());
	if (tmp.size())
	{
		for (int val : tmp)
			dfn.push_back(val);
	}
	cout << ans << endl;
	for (int val : dfn)
	{
		cout << val << " ";
	}
	cout << endl;
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	int test = 1;
	// cin >> test;
	for (int i = 1; i <= test; i++)
	{
		solve();
	}
	return 0;
}
相关推荐
艾莉丝努力练剑18 分钟前
【LeetCode&数据结构】单链表的应用——反转链表问题、链表的中间节点问题详解
c语言·开发语言·数据结构·学习·算法·leetcode·链表
_殊途2 小时前
《Java HashMap底层原理全解析(源码+性能+面试)》
java·数据结构·算法
珊瑚里的鱼5 小时前
LeetCode 692题解 | 前K个高频单词
开发语言·c++·算法·leetcode·职场和发展·学习方法
秋说6 小时前
【PTA数据结构 | C语言版】顺序队列的3个操作
c语言·数据结构·算法
lifallen7 小时前
Kafka 时间轮深度解析:如何O(1)处理定时任务
java·数据结构·分布式·后端·算法·kafka
liupenglove7 小时前
自动驾驶数据仓库:时间片合并算法。
大数据·数据仓库·算法·elasticsearch·自动驾驶
python_tty8 小时前
排序算法(二):插入排序
算法·排序算法
然我8 小时前
面试官:如何判断元素是否出现过?我:三种哈希方法任你选
前端·javascript·算法
F_D_Z9 小时前
【EM算法】三硬币模型
算法·机器学习·概率论·em算法·极大似然估计
秋说9 小时前
【PTA数据结构 | C语言版】字符串插入操作(不限长)
c语言·数据结构·算法