题目链接: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. LeetCode707 设计链表

    设计链表的实现.您可以选择使用单链表或双链表.单链表中的节点应该具有两个属性:val 和 next.val 是当前节点的值,next 是指向下一个节点的指针/引用.如果要使用双向链表,则还需要一个属性 ...

  2. LeetCode542 01矩阵

    给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离. 两个相邻元素间的距离为 1 . 示例 1: 输入: 0 0 0 0 1 0 0 0 0 输出: 0 0 0 0 1 0 0 0 ...

  3. HashMap为什么效率高?来看看这个小demo

    一.前情回顾:在程序中有时候需要存放对象,容器应运而生.容器分为集合和Map.集合在这里不说,说说Map.Map在英语中是地图的意思,这个名字真是起的好,可以让人顾名思义.Map,就是存放键值对的结构 ...

  4. (十八)configparser模块

    configparser模块一般是用来处理配置文件的,如: [DEFAULT] ServerAliveInterval = 45 Compression = yes CompressionLevel ...

  5. 【Linux】添加硬盘不需要重启服务器

    添加硬盘之后,不用重启服务器 执行下面的语句 ls /sys/class/scsi_host 查看下面有多少host 我这里有三个host 分别执行 echo "- - -" &g ...

  6. Spring Boot Scheduled定时任务特性

    SpringBoot中的Scheduled定时任务是Spring Boot中非常常用的特性,用来执行一些比如日切或者日终对账这种定时任务 下面说说使用时要注意的Scheduled的几个特性 Sched ...

  7. RocketMQ在linx安装及其有关问题解决

    Linx安装和使用: rocketmq官网:http://rocketmq.apache.org/ 首先安装JDK(推荐使用JDK1.8),并配置环境变量 下载rocketmq压碎包并解压到指定目录 ...

  8. 十一、UART&TTY驱动

    Linux系统中UART驱动和TTY驱动两者有着紧密的关系,它们不像I2C和SPI驱动是单独一个模块,分析时应当将它们看成一个整体来分析.UART驱动部分依赖于硬件平台,而TTY驱动和具体的平台无关. ...

  9. Docker镜像仓库Harbor安装

    export VERSION=18.06 && curl -fsSL http://rainbond-pkg.oss-cn-shanghai.aliyuncs.com/releases ...

  10. winform 扫码识别二维码

    因为公司业务需求,需要在Windows系统下调用摄像头识别二维码需求,就有了这个功能. 我根据网上网友提供的一些资料,自己整合应用到项目中,效果还不错(就是感觉像素不是太好) 现在将调用摄像头+识别二 ...