码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2020-08-02 22:19:04      阅读:108      评论:0      收藏:0      [点我收藏+]

标签:要求   close   span   sum   图片   amp   col   tps   clu   

题目链接:https://codeforc.es/contest/1388/problem/D

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

思路:要使得ans最大,那么肯定是a[i]为正数的都尽量早的累加,为负数的都尽量晚的累加,那么现在只需要考虑如何遍历就行了,题目已经说明是

有向无环图,那么首先想到的就应该是拓扑排序,从入度为0开始,这样才能最大限度的累加

遍历完之后, 再从出度为0的先进行操作,这样剩下的负数就不会累加到其他数上

技术图片
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define ll long long
  4 #define ull unsigned long long
  5 #define pb push_back
  6 const int maxn=2e5+10;
  7 const int mod=1e9+7;
  8 ll a[maxn];
  9 ll b[maxn];
 10 int ru[maxn];
 11 int chu[maxn];
 12 vector<int>E[maxn];
 13 vector<int>G[maxn];
 14 int vis[maxn];
 15 
 16 
 17 
 18 int main()
 19 {
 20     ios::sync_with_stdio(false);
 21     cin.tie(0);
 22     int n;
 23     cin>>n;
 24     ll sum=0;
 25     for(int i=1;i<=n;i++)
 26     {
 27         cin>>a[i];
 28     }
 29     for(int i=1;i<=n;i++)
 30     {
 31         cin>>b[i];
 32     }
 33     vector<int>ans;
 34     for(int i=1;i<=n;i++)
 35     {
 36         if(b[i]==-1)
 37             continue;
 38         ru[b[i]]++;
 39         chu[i]++;
 40         E[i].pb(b[i]);
 41         G[b[i]].pb(i);
 42     }
 43     queue<int>q;
 44     for(int i=1;i<=n;i++)
 45     {
 46         if(ru[i]==0)
 47         {
 48             q.push(i);
 49         }
 50     }
 51     //cout<<sum<<‘\n‘;
 52     while(!q.empty())
 53     {
 54         int u=q.front();
 55         q.pop();
 56         for(auto &v:E[u])
 57         {
 58             ru[v]--;
 59             if(a[u]>=0)
 60             {
 61                 a[v]+=a[u];
 62                 sum+=a[u];
 63                 ans.pb(u);
 64                 vis[u]=1;
 65             }
 66             if(ru[v]==0)
 67             {
 68                 q.push(v);
 69             }
 70         }
 71     }
 72     //cout<<sum<<‘\n‘;
 73     queue<int>qh;
 74     for(int i=1;i<=n;i++)
 75     {
 76         if(chu[i]==0&&vis[i]==0)
 77         {
 78             qh.push(i);
 79         }
 80     }
 81     //cout<<sum<<‘\n‘;
 82     while(!qh.empty())
 83     {
 84         int u=qh.front();
 85         qh.pop();
 86         if(vis[u]==0)
 87         {
 88             sum+=a[u];
 89             ans.pb(u);
 90         }
 91         for(auto &v:G[u])
 92         {
 93             chu[v]--;
 94             if(chu[v]==0)
 95                 qh.push(v);
 96         }
 97     }
 98     cout<<sum<<\n;
 99     for(auto &v:ans)
100     {
101         cout<<v<<" ";
102     }
103 
104 
105 
106 
107 }
View Code

 

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

标签:要求   close   span   sum   图片   amp   col   tps   clu   

原文地址:https://www.cnblogs.com/winfor/p/13420289.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!