CodeForces 1388D Captain Flint and Treasure

題意node

給長度爲\(n\)的序列\(a[n]\)\(b[n]\),初始時\(ans=0\),有如下操做:ios

  • \(ans=ans+a[i]\)
  • 若是\(b[i]\neq-1\),則\(a[b[i]]=a[b[i]]+a[i]\)

問每一個元素操做一次後,\(ans\)最大爲多少,並輸出操做序列c++

分析spa

對於一個數,若是他有前驅的話,能夠考慮對於其某些前驅進行操做後再操做該數,那麼畫一個前驅圖能夠發現,這是一個拓撲排序的題,操做到某個節點時code

  • 若是該節點的值大於\(0\),說明將其操做到後續節點必定是更優的
  • 不然,這個節點必定要晚於其後續節點操做,不然會將該節點的值再貢獻一次

那麼拓撲排序的時候維護一個隊列和一個棧,對於值大於\(0\)的節點,將其放入隊列中,而後將其值加入後續節點,不然將其放入棧中(由於若連續兩個節點值都小於\(0\),那麼應先操做後續節點),最後輸出便可排序

#pragma GCC optimize(3, "Ofast", "inline")
 
#include <bits/stdc++.h>
 
#define start ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define int ll
#define ls st<<1
#define rs st<<1|1
#define pii pair<int,int>
#define rep(z, x, y) for(int z=x;z<=y;++z)
#define repd(z, x, y) for(int z=x;z>=y;--z)
#define com bool operator<(const node &b)const
using namespace std;
mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
const int maxn = (ll) 3e5 + 5;
const int mod = 998244353;
const int inf = 0x3f3f3f3f;
int T = 1;
int a[maxn], b[maxn];
vector<int> v[maxn];
int in[maxn];
 
void solve() {
    int n;
    cin >> n;
    rep(i, 1, n)cin >> a[i];
    rep(i, 1, n) {
        cin >> b[i];
        if (b[i] != -1) {
            v[i].push_back(b[i]);
            ++in[b[i]];
        }
    }
    int ans = 0;
    queue<int> q;
    rep(i, 1, n) {
        if (in[i] == 0) {
            q.push(i);
        }
    }
    vector<int> tmp;
    stack<int> last;
    while (!q.empty()) {
        int now = q.front();
        if (a[now] > 0)
            tmp.push_back(now);
        else
            last.push(now);
        ans += a[now];
        q.pop();
        for (auto &to:v[now]) {
            if (a[now] > 0)
                a[to] += a[now];
            --in[to];
            if (in[to] == 0) {
                q.push(to);
            }
        }
    }
    cout << ans << '\n';
    for (auto &to:tmp)cout << to << ' ';
    while (!last.empty()) {
        cout << last.top() << ' ';
        last.pop();
    }
}
 
signed main() {
    start;
    while (T--)
        solve();
    return 0;
}
相關文章
相關標籤/搜索