题目链接:Captain Flint and Treasure

题意:

一种操作为 选一个下标 使得ans+=a[i] 且 把a[b[i]]+a[i]   要求每个下标都进行一种这样的操作,问怎么样的操作顺序才能使得ans最大

题解:

在题目面板的输入里面说了这是一个有向无环图,我怎么没看到题目上说这是一个图?

我们可以把那个操作当作一条边,而且那个操作还是单向的,所以就成有向无环图了

如果a[i]>=0,那么肯定需要进行这种操作(因为会增加ans的值)。如果a[i]为负数,那么肯定是尽量减少这种操作

那么对于a[i]>=0的数,我们对入度为0的点进行拓扑排序,以使得a[i]尽可能的为最后的答案ans做贡献

对于a[i]<0的数,那么就从出度为0的点开始进行拓扑排序

代码:

  1 #include<stack>
2 #include<queue>
3 #include<map>
4 #include<cstdio>
5 #include<cstring>
6 #include<iostream>
7 #include<algorithm>
8 #include<vector>
9 #define fi first
10 #define se second
11 #define pb push_back
12 using namespace std;
13 typedef long long ll;
14 const int maxn=2e5+10;
15 const int mod=1e9+7;
16 const double eps=1e-8;
17 ll a[maxn];
18 ll b[maxn];
19 ll ru[maxn];
20 ll chu[maxn];
21 vector<ll>E[maxn];
22 vector<ll>G[maxn];
23 ll vis[maxn];
24 int main()
25 {
26 ios::sync_with_stdio(false);
27 cin.tie(0);
28 ll n;
29 cin>>n;
30 ll sum=0;
31 for(ll i=1;i<=n;i++)
32 {
33 cin>>a[i];
34 }
35 for(ll i=1;i<=n;i++)
36 {
37 cin>>b[i];
38 }
39 vector<ll>ans;
40 for(ll i=1;i<=n;i++)
41 {
42 if(b[i]==-1)
43 continue;
44 ru[b[i]]++;
45 chu[i]++;
46 E[i].pb(b[i]); //存放正向边的vector
47 G[b[i]].pb(i); //存放逆向边的vector
48 }
49 queue<ll>q;
50 for(ll i=1;i<=n;i++) //找出入度为0的点,并从此开始进行拓扑排序
51 {
52 if(ru[i]==0) //而且我们只处理ai值大于0的点
53 {
54 q.push(i);
55 }
56 }
57 while(!q.empty())
58 {
59 ll u=q.front();
60 q.pop();
61 for(auto &v:E[u])
62 {
63 ru[v]--;
64 if(a[u]>=0) //根据题目描述一个点i指向下一个点b[i],那么这个边只会有一条,所以u这个点虽然在for循环
65 { //内,但是这个循环只会循环一次
66 a[v]+=a[u];
67 sum+=a[u];
68 ans.pb(u); //ans存放路径,因为最后要输出
69 vis[u]=1;
70 }
71 if(ru[v]==0)
72 {
73 q.push(v);
74 }
75 }
76 }
77 queue<ll>r;
78 for(ll i=1;i<=n;i++)
79 {
80 if(chu[i]==0&&vis[i]==0)
81 {
82 r.push(i);
83 }
84 }
85 while(!r.empty())
86 {
87 ll u=r.front();
88 r.pop();
89 if(vis[u]==0)
90 {
91 sum+=a[u];
92 ans.pb(u);
93 }
94 for(auto &v:G[u])
95 {
96 chu[v]--;
97 if(chu[v]==0)
98 r.push(v);
99 }
100 }
101 printf("%lld\n",sum);
102 ll len=ans.size();
103 for(ll i=0;i<len;++i)
104 {
105 // if(i==len-1)
106 // printf("%lld\n",ans[i]);
107 // else
108 printf("%lld ",ans[i]);
109 }
110 return 0;
111 }

Codeforces Round #660 (Div. 2) Captain Flint and Treasure 拓扑排序(按照出度、入读两边拓扑排序)的更多相关文章

  1. Codeforces Round #660 (Div. 2) A. Captain Flint and Crew Recruitment、Captain Flint and a Long Voyage

    题目链接:Captain Flint and Crew Recruitment 题意: t组输入,每一组输入一个n.这里我们说一下题目定义的近似质数概念: "如果可以将正整数x表示为p⋅q, ...

  2. Codeforces Round #660 (Div. 2) A、B、C题解

    A. Captain Flint and Crew Recruitment #构造 题目链接 题意 定义一类正整数,能够被\(p*q\)表示,其中\(p.q(1<p<q)\)均为素数,称之 ...

  3. Codeforces Round #660 (Div. 2)

    A. Captain Flint and Crew Recruitment 题意:定义了一种数(接近质数),这种数可以写成p*q并且p和q都是素数,问n是否可以写成四个不同的数的和,并且保证至少三个数 ...

  4. Codeforces Round #660 (Div. 2) Uncle Bogdan and Country Happiness dfs

    题目链接:Uncle Bogdan and Country Happiness 题意: t组输入,每组数据输入如下 首先一个n代表有n个城市,所有城市总人数为m,后面输入pi表示第i个城市的居住人数, ...

  5. Codeforces Round #660 (Div. 2) C. Uncle Bogdan and Country Happiness (DFS)

    题意:有\(n\)个人,每个人居住在某个节点,所有人都在节点\(1\)上班,下班后沿着最短路径回家,在回家途中心情可能会变差(心情只会变差不会变好),每个节点都有一个开心值,开心值等于所有经过时的好心 ...

  6. Codeforces Round #355 (Div. 2) D. Vanya and Treasure dp+分块

    题目链接: http://codeforces.com/contest/677/problem/D 题意: 让你求最短的从start->...->1->...->2->. ...

  7. Codeforces Round #355 (Div. 2) D. Vanya and Treasure 分治暴力

    D. Vanya and Treasure 题目连接: http://www.codeforces.com/contest/677/problem/D Description Vanya is in ...

  8. Codeforces Round #355 (Div. 2) D. Vanya and Treasure

    题目大意: 给你一个n × m 的图,有p种宝箱, 每个点上有一个种类为a[ i ][ j ]的宝箱,a[ i ][ j ] 的宝箱里有 a[ i ][ j ] + 1的钥匙,第一种宝箱是没有锁的, ...

  9. Codeforces Round #271 (Div. 2)题解【ABCDEF】

    Codeforces Round #271 (Div. 2) A - Keyboard 题意 给你一个字符串,问你这个字符串在键盘的位置往左边挪一位,或者往右边挪一位字符,这个字符串是什么样子 题解 ...

随机推荐

  1. 【剑指 Offer】03.1.不修改数组找出重复的数字

    找出数组中重复的数字. 在一个长度为 n + 1 的数组 nums 里的所有数字都在 1-n 的范围内.所以数组中至少有一个是重复的.请找出数组中任意一个重复的数字. 示例 1: 输入: [2, 3, ...

  2. Linux性能相关命令

    Linux性能相关命令 目录 Linux性能相关命令 1. 查看硬盘相关信息 2. 查看CPU相关信息 3. 查看内存相关信息 4. 查看进程运行的信息 1. 查看硬盘相关信息 cat /proc/s ...

  3. 通过JS逆向ProtoBuf 反反爬思路分享

    前言 本文意在记录,在爬虫过程中,我首次遇到Protobuf时的一系列问题和解决问题的思路. 文章编写遵循当时工作的思路,优点:非常详细,缺点:文字冗长,描述不准确 protobuf用在前后端传输,在 ...

  4. 【Linux】扩大swap分区

    今天安装oracle的时候,提示我swap分区过小.需要最少3g以上 但是安装系统了,想要扩大swap分区怎么办呢 下面来介绍如何扩大swap分区 按步骤介绍 Red Hat linux 如何增加sw ...

  5. bash5.0参考手册

    Bash Reference Manual a.summary-letter { text-decoration: none } blockquote.indentedblock { margin-r ...

  6. IOC技术在前端项目中的应用

    目录 背景 什么是IOC 如何实现一个IOC 第一步:实现一个容器 第二步:用好装饰器 第三步:使用容器 扩展和展望 最后 背景 前端发展至今已经过去30余年,前端应用领域在不断壮大的过程中,也变得越 ...

  7. Nginx架构赏析

    淘宝的某位大佬曾经做过测试,在一台24G内存的机器上,Nginx的最大并发连接数达到了200万.同学们听到这个结论后,是不是被Nginx的超高性能深深折服了,它内部的架构设计究竟是怎么样的呢?这篇文章 ...

  8. Redis 实战 —— 07. 复制、处理故障、事务及性能优化

    复制简介 P61 关系型数据库通常会使用一个主服务器 (master) 向多个从服务器 (slave) 发送更新,并使用从服务器来处理所有读请求. Redis 也采用了同样的方法实现自己的复制特性,并 ...

  9. h3c交换机配置ssh密码验证登录方式

    一.背景: 1.由于PC机串口不支持热插拔,请不要在交换机带电的情况下,将串口插入或者拔出PC机.当连接PC和交换机时,请先安装配置电缆的DB-9端到PC机,再连接RJ-45到交换机:在拆下时,先拔出 ...

  10. ubuntu 更改U盘设备分区/dev/sdb4 标识

    备份u盘分区表 代码: sudo sfdisk -d /dev/sdb > sdb_table 修改sdb_table文件 代码: gedit sdb_table 恢复u盘分区表 代码: sud ...