Captain Flint and Treasure

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

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

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

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

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
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define pb push_back
const int maxn=2e5+10;
const int mod=1e9+7;
ll a[maxn];
ll b[maxn];
int ru[maxn];
int chu[maxn];
vector<int>E[maxn];
vector<int>G[maxn];
int vis[maxn];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin>>n;
    ll sum=0;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    for(int i=1;i<=n;i++)
    {
        cin>>b[i];
    }
    vector<int>ans;
    for(int i=1;i<=n;i++)
    {
        if(b[i]==-1)
            continue;
        ru[b[i]]++;
        chu[i]++;
        E[i].pb(b[i]);
        G[b[i]].pb(i);
    }
    queue<int>q;
    for(int i=1;i<=n;i++)
    {
        if(ru[i]==0)
        {
            q.push(i);
        }
    }
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        for(auto &v:E[u])
        {
            ru[v]--;
            if(a[u]>=0)
            {
                a[v]+=a[u];
                sum+=a[u];
                ans.pb(u);
                vis[u]=1;
            }
            if(ru[v]==0)
            {
                q.push(v);
            }
        }
    }
    queue<int>qh;
    for(int i=1;i<=n;i++)
    {
        if(chu[i]==0&&vis[i]==0)
        {
            qh.push(i);
        }
    }
    while(!qh.empty())
    {
        int u=qh.front();
        qh.pop();
        if(vis[u]==0)
        {
            sum+=a[u];
            ans.pb(u);
        }
        for(auto &v:G[u])
        {
            chu[v]--;
            if(chu[v]==0)
                qh.push(v);
        }
    }
    cout<<sum<<'
';
    for(auto &v:ans)
    {
        cout<<v<<" ";
    }




}
原文地址:https://www.cnblogs.com/iloveysm/p/13443029.html