CodeForces 738E Subordinates

排序,构造。

相当于告诉我们一棵树$n$个节点,每个节点在哪一层,至少需要移动多少个节点,才能让这些节点变成一棵树。

按照层次排个序移动一下就可以了,优先选择那些不是$s$但是层次是$0$的节点,如果没有,那么再选择层次最高的。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<ctime>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0);
void File()
{
    freopen("D:\in.txt","r",stdin);
    freopen("D:\out.txt","w",stdout);
}
template <class T>
inline void read(T &x)
{
    char c = getchar();
    x = 0;
    while(!isdigit(c)) c = getchar();
    while(isdigit(c))
    {
        x = x * 10 + c - '0';
        c = getchar();
    }
}

struct X
{
    int id,c;
}t[200010];
int n,s,ans;

bool cmp(X a, X b)
{
    return a.c<b.c;
}

int flag[200010];

queue<int>Q;

int main()
{
    cin>>n>>s;
    for(int i=1;i<=n;i++)
    {
        t[i].id=i;
        cin>>t[i].c;
        if(t[i].c==0&&i!=s)
        {
            flag[i]=1;
            ans++;
            Q.push(i);
        }
    }

    if(t[s].c!=0) ans++,t[s].c=0;

    sort(t+1,t+1+n,cmp);

    int wei=n;

    for(int i=1;i<=n;i++)
    {
        if(flag[t[i].id]==1) continue;
        if(t[i].c==t[i-1].c) continue;
        if(t[i].c==t[i-1].c+1) continue;

        int need=t[i].c-t[i-1].c-1;
        int f=0;

        while(1)
        {
            f++;
            if(!Q.empty()) Q.pop();
            else
            {
                if(wei<i) break;
                flag[t[wei].id]=1;
                wei--; ans++;
                if(wei<i) break;
            }
            if(f==need) break;
        }
        if(wei<i) break;
    }

    cout<<ans<<endl;

    return 0;
}
原文地址:https://www.cnblogs.com/zufezzt/p/6393411.html