UOJ278 【UTR #2】题目排列顺序

本文作者:ljh2000 
作者博客:http://www.cnblogs.com/ljh2000-jump/
转载请注明出处,侵权必究,保留最终解释权!

 

 

 

题目链接: http://uoj.ac/contest/36/problem/278

 

 

 正解:排序...

 解题报告:

  考场上我是make了几组数据,然后用暴力跑跑才发现的结论...

  比如说:显然2只能由1转移过来,3只能由2转移过来,并且,相同权值的话,最后一个显然是最小的,不然就可以再加一了呀...

  所以按权值为第一关键字(从小到大),下标为第二关键字(从大到小)排序,依次编号即可。我在考场上写的是线性做法,就是对于每个权值挂个链就ok了。

 

//It is made by ljh2000
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <string>
using namespace std;
typedef long long LL;
const int MAXN = 200011;
int n,f[MAXN],a[MAXN],cnt;
int ecnt,first[MAXN],to[MAXN],next[MAXN];

inline void link(int x,int y){ 
	next[++ecnt]=first[x]; first[x]=ecnt; to[ecnt]=y;
}

inline int getint(){
    int w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && c!='-') c=getchar();
    if(c=='-') q=1,c=getchar(); while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w;
}

inline void work(){
	n=getint(); for(int i=1;i<=n;i++) a[i]=getint(),link(a[i],i);
	cnt=0;
	for(int i=1;i<=n;i++) {
		if(first[i]==0) break;		
		for(int j=first[i];j;j=next[j]) {
			a[to[j]]=++cnt;
		}
	}
	for(int i=1;i<=n;i++) printf("%d ",a[i]);
}

int main()
{
    work();
    return 0;
}

  

posted @ 2017-01-13 09:25  ljh_2000  阅读(246)  评论(0编辑  收藏  举报