首页 > Web开发 > 详细

[题解] [JSOI2010] 排名

时间:2020-02-04 12:25:11      阅读:64      评论:0      收藏:0      [点我收藏+]

题面

题解

题目很简单, 用优先队列维护拓扑序即可
但是他要我们求的东西比较诡异, 导致贪心的策略会不同
对于第一问, 我们一般的思路是直接维护正的拓扑序, 每次选最小的更新
但这样不一定是最优的, 因为选择了当前最小的可能使得更小的拓扑序排在后面, 这样字典序就不一定是最小的了
所以我们维护反的拓扑序, 每次选最大的更新
第二问可以直接用大根堆维护正的拓扑序就行了

Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
const int N = 200005; 
using namespace std;

int n, a[N], deg[N], in[N], ans[N], head[N], cnt;
struct edge { int to, nxt; } e[N];
priority_queue<int> q; 

template < typename T >
inline T read()
{
    T x = 0, w = 1; char c = getchar();
    while(c < '0' || c > '9') { if(c == '-') w = -1; c = getchar(); }
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * w; 
}

inline void adde(int u, int v) { e[++cnt] = (edge) { v, head[u] }, head[u] = cnt; }

int main()
{
    n = read <int> ();
    for(int i = 1; i <= n; i++)
    {
    a[i] = read <int> ();
    if(a[i]) adde(a[i], i), deg[a[i]]++, in[i]++; 
    }
    cnt = n; 
    for(int i = 1; i <= n; i++)
    if(!deg[i]) q.push(i);
    while(!q.empty())
    {
    int u = q.top(); q.pop();  
    ans[u] = cnt--;
    if(!(--deg[a[u]])) q.push(a[u]); 
    }
    for(int i = 1; i <= n; i++)
    printf("%d%c", ans[i], i == n ? '\n' : ' '); 
    cnt = 0;
    for(int i = 1; i <= n; i++)
    if(!in[i]) q.push(i); 
    while(!q.empty())
    {
    int u = q.top(); q.pop();
    ans[u] = ++cnt; 
    for(int v, i = head[u]; i; i = e[i].nxt)
    {
        v = e[i].to;
        q.push(v); 
    }
    }
    for(int i = 1; i <= n; i++)
    printf("%d%c", ans[i], i == n ? '\n' : ' '); 
    return 0; 
}

[题解] [JSOI2010] 排名

原文:https://www.cnblogs.com/ztlztl/p/12258659.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!