这道题目的原则很简单,就是把所有出现的x排个序,然后如果后面的比前面大就把后面的做父节点,相等就从没出现过的数字中取出一个。
怎么保证没出现过的数字足够满足相等的数字呢?其实这道题已经保证了对于任何一个数字k,子树最大值<=k的位置i不会超过k个,也就是说k放进去后面有多少个和k相等的数字,必定存在多少个没出现过且小于k的数字(在更大数字出现之前)
比如 1 2 5 3 4就有5个子树最大值小于等于5,而1 2 5 3 6 4则只有4个子树最大值小于等于5.总之就是剩余的数字肯定能把x数组里面重复的数字填满,程序里面的排序过程用桶排序代替。book数组实际上是x
#include<bits/stdc++.h> using namespace std; set<int> unused; int book[1010]; int in[1010]; int tot; int main() { int n; scanf("%d",&n); bool flag=true; for(int i=1;i<n;i++) { int x,y; scanf("%d%d",&x,&y); if(x>y) swap(x,y); if(y!=n) { flag=false; } book[x]++; in[++tot]=x; } if(!flag) { printf("NO\n"); return 0; } int num=0; for(int i=1;i<n;i++) { num+=book[i]; if(num>i) { printf("NO\n"); return 0; } } printf("YES\n"); for(int i=1;i<n;i++) { unused.insert(i); } int last=-1; for(int i=1;i<n;i++) { if(book[i]) { unused.erase(i); book[i]--; if(last!=-1) { printf("%d %d\n",last,i); } last=i; } while(book[i]) { book[i]--; int now=*unused.begin(); printf("%d %d\n",last,now); last=now; unused.erase(unused.begin()); } } printf("%d %d\n",last,n); }
数组
原文地址:https://www.cnblogs.com/lishengkangshidatiancai/p/10166487.html
时间: 2024-11-02 09:25:16