Codeforces Round #660 (Div. 2) Captain Flint and Treasure 拓扑排序(按照出度、入读两边拓扑排序)
题目链接: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 拓扑排序(按照出度、入读两边拓扑排序)的更多相关文章
- 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, ...
- Codeforces Round #660 (Div. 2) A、B、C题解
A. Captain Flint and Crew Recruitment #构造 题目链接 题意 定义一类正整数,能够被\(p*q\)表示,其中\(p.q(1<p<q)\)均为素数,称之 ...
- Codeforces Round #660 (Div. 2)
A. Captain Flint and Crew Recruitment 题意:定义了一种数(接近质数),这种数可以写成p*q并且p和q都是素数,问n是否可以写成四个不同的数的和,并且保证至少三个数 ...
- Codeforces Round #660 (Div. 2) Uncle Bogdan and Country Happiness dfs
题目链接:Uncle Bogdan and Country Happiness 题意: t组输入,每组数据输入如下 首先一个n代表有n个城市,所有城市总人数为m,后面输入pi表示第i个城市的居住人数, ...
- Codeforces Round #660 (Div. 2) C. Uncle Bogdan and Country Happiness (DFS)
题意:有\(n\)个人,每个人居住在某个节点,所有人都在节点\(1\)上班,下班后沿着最短路径回家,在回家途中心情可能会变差(心情只会变差不会变好),每个节点都有一个开心值,开心值等于所有经过时的好心 ...
- Codeforces Round #355 (Div. 2) D. Vanya and Treasure dp+分块
题目链接: http://codeforces.com/contest/677/problem/D 题意: 让你求最短的从start->...->1->...->2->. ...
- 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 ...
- Codeforces Round #355 (Div. 2) D. Vanya and Treasure
题目大意: 给你一个n × m 的图,有p种宝箱, 每个点上有一个种类为a[ i ][ j ]的宝箱,a[ i ][ j ] 的宝箱里有 a[ i ][ j ] + 1的钥匙,第一种宝箱是没有锁的, ...
- Codeforces Round #271 (Div. 2)题解【ABCDEF】
Codeforces Round #271 (Div. 2) A - Keyboard 题意 给你一个字符串,问你这个字符串在键盘的位置往左边挪一位,或者往右边挪一位字符,这个字符串是什么样子 题解 ...
随机推荐
- 【SpringBoot1.x】 Docker
SpringBoot1.x Docker 核心概念 Docker 是一个开源的应用容器引擎,是一个轻量级容器技术.Docker 支持将软件编译成一个镜像,然后在镜像中各种软件做好配置,将镜像发布出去, ...
- Centos 6 下安装 OSSEC-2.8.1 邮件告警 (二)
Ossec 配置邮件通知 ## 1 安装软件包: yum install -y sendmail mailx cyrus-sasl cyrus-sasl-plain #安装postfix邮件相关的软件 ...
- vim 手动添加脚本头部信息
vim /root/.vimrc 8,1 全部 set autoindent set tabstop=5 set shiftwidth=4 function AddTitle() call setli ...
- 【Linux】find查找空文件夹
linux下批量删除空文件(大小等于0的文件)的方法 find . -name "*" -type f -size 0c | xargs -n 1 rm -f 就是删除1k大小的文 ...
- DDIC_TYPELENG_INCONSISTENT错误的解决办法
当执行某个TCODE,例如SM66,出现类似如下的dump界面 大概意思就是说是ddic种的某个数据类型有问题,可能是数据结构,可能是数据元素或者是表等等 通过查阅资料了解到,对于note122290 ...
- 入门OJ:扫雪
扫雪1 题目描述 大雪履盖了整个城市,市政府要求冬季服务部门尽快将一些街道(列在一份清单中)的积雪清除掉以恢复交通,整个城市由许多交叉路口和街道构成,当然任意两个交叉路口都是直接或间接连通的,清单给出 ...
- 解决安装mysql动态库libstdc++.so.6、libc.so.6版本过低问题
初始化mysql报错: ./bin/mysqld: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by ...
- MySQL增删改操作
增删改操作 增加 看语法 1. 插入完整数据(顺序插入) 语法一: INSERT INTO 表名(字段1,字段2,字段3-字段n) VALUES(值1,值2,值3-值n); #指定字段来插入数据,插入 ...
- Vue中:error 'XXXXX' is not defined no-undef解决办法
Vue中:error 'XXXXX' is not defined no-undef解决办法 报错内容: × Client Compiled with some errors in 7.42s √ S ...
- vim 行号的显示与隐藏
通常我们在使用vim编辑器的时候,需要显示和隐藏行号 隐藏行号: 1.首先我们vim 1.txt (进入我们编辑的文档),如下,此时是显示行号的 2.按一下esc键,并输入:(冒号),完成效果 ...