zoukankan      html  css  js  c++  java
  • 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<<" ";
        }
    
    
    
    
    }
  • 相关阅读:
    VS无法打开类视图
    C#中的Boolean类型
    Some websites to learn Ubuntun
    HOW TO : Install Eclipse with C/C++ in Ubuntu 12.04
    [转载]Android开发之旅:环境搭建及HelloWorld
    C#学习笔记—了解C#
    C#继承机制
    使用U盘安装Ubuntu
    [Z]ubuntu12.04搭建android开发环境
    Windows程序的调用方法
  • 原文地址:https://www.cnblogs.com/iloveysm/p/13443029.html
Copyright © 2011-2022 走看看