IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> Captain Flint and Treasure(CodeForces - 1388D ) 【拓扑排序】 -> 正文阅读

[数据结构与算法]Captain Flint and Treasure(CodeForces - 1388D ) 【拓扑排序】

芬特船长参与了另一个寻宝行动,但只发现了一个奇怪的问题。这个问题可能与宝藏的位置有关,也可能与此无关。这就是为什么弗林特船长决定把解决这个问题的任务留给他的船员,并给了他们一个高得离谱的奖励:一天假。

有两个数组a和b的长度n。初始ans = 0,定义如下操作:

1.选择位置i(1≤i≤n);

2.在ans中加上a[i];

3.如果b[i]≠- 1,则将a[b[i]]中加上a[i]。

对每个i(1≤i≤n)执行一次操作,可以得到的最大ans值是多少?

Bogdan叔叔渴望得到奖励,所以他请求你帮他找到最优的位置顺序来对它们进行操作。

Input

第一行包含整数n(1≤n≤2?105)——数组的长度a和b。

第二行包含n整数a1,a2,…,an(?106≤ai≤106)。

第三行包含n整数b1,b2,…,bn(1≤bi≤n或bi=?1)。

附加约束:保证对于任意i(1≤i≤n),序列b[i],b[b[i]],b[b[b[i]]],… 都不是循环的,即总是以?1结束。

Output

在第一行中,打印您可以获得的最大ans字体。

在第二行中,打印操作顺序:nn不同的整数p1,p2,…,pn(1≤pi≤n)。pi是在第i步应该选择的位置。如果有多个订单,打印其中任何一个。

Examples

Input

3
1 2 3
2 3 -1

Output

10
1 2 3

Input

2
-1 100
2 -1

Output

99
2 1

Input

10
-10 -1 2 2 5 -2 -3 -4 2 -6
-1 -1 2 2 -1 5 5 7 7 9

Output

-9
3 5 6 1 9 4 10 7 8 2

第一个样例: 1 + (1 + 2) + (3 + 3) = 10

代码

//博客,拓扑排序
#include "stdio.h"
#include "algorithm"
#include "iostream"
#include "string.h"
#include "vector"
#include "queue"
using namespace std;
int n,m;
long long sum=0;
long long a[200009],b[200009],c[200009];
//c[i]录编号为i的入度
int main()
{

	queue<int>q;//记录入度为零的编号
	vector<int>good,bad;
//good数组记录a数组中值大于0(正数的编号)的编号
//bad 数组记录a叔祖中值小于等于0(负数的编号)的编号
	cin>>n;
	for(int i=1; i<=n; i++)
		cin>>a[i];
	for(int i=1; i<=n; i++)
	{
		cin>>b[i];
		if(b[i]!=-1)
			c[b[i]]++;
//c[b[i]记录编号为b[i]的入度
	}
	for(int i=1; i<=n; i++)
	{
		if(c[i]==0)
			q.push(i);
	}
	while(!q.empty())
	{
		int u=q.front();
		q.pop();
		sum+=a[u];
		if(a[u]>0)
		{
			good.push_back(u);
			a[b[u]]+=a[u];
			c[b[u]]--;
		}
		else
		{
			bad.push_back(u);
			c[b[u]]--;
		}
		if(c[b[u]]==0)
			q.push(b[u]);
	}
	cout<<sum<<endl;
	for(int i=0; i<good.size(); i++)//正着来使一些正数可以留后代 (会加到其他数上再加到ans(sum)中) 
		cout<<good[i]<<' ';
	for(int i=bad.size()-1; i>=0; i--)//倒着来使负数断子绝孙 (不会加到其他数上再加到ans(sum)中) 
		cout<<bad[i]<<' ';
}
//为什么先输入正数的编号,再输入负数的编号
//就是把上面的55-58行写成 (交换一下顺序) 
/*
for(int i=bad.size()-1; i>=0; i--)
		cout<<bad[i]<<' ';
for(int i=0; i<good.size(); i++)
		cout<<good[i]<<' ';
*/
/*
例1	     1   -5   4 
        -1   1    2
(先正后负)ans(max)=4+1+(-5+4)=4   顺序3 1 2 
(先负后正)ans=-5+4+(1-5)=-5  顺序 2 3 1 

例2      1   -5   9 
		-1    1   2
(先正后负)ans(max)=9+1+(-5+9)=14   顺序3 1 2 
(先负后正)ans=-5+9+(1-5)=0  顺序 2 3 1 


我们发现:
先正后负可以令某些负数变大(-5-->-1)或变为正数(-5-->4) 
先负后正可以另某些正数变小或变为负数 
 
*/ 
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-05-08 08:20:57  更:2022-05-08 08:23:21 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 3:45:10-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码