CF1041E Tree Reconstruction_构造_思维题

不难发现,每次询问结果一定是 (i,n)(i,n), 而 ii 出现的次数恰好是 iiii' 的距离(ii' 是第一个不与 ii 相等的数)。我们可以将这颗树构造成一条链,然后就 AC 了。
Code:

#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int maxn = 1000 + 5;
int idx1[maxn], idx2[maxn], arr[maxn],A[maxn], n, pos;
bool cmp(int i,int j){ return idx1[i] < idx1[j]; }
inline bool insert(int x, int h){
    for(int i = h;i <= n; ++i) if(!arr[i]) { arr[i] = x; return true; }
    return false;
}
inline void fail(){  printf("NO"); exit(0); }
int main()
{
    scanf("%d",&n);
    for(int i = 1;i < n; ++i) { scanf("%d%d",&idx1[i],&idx2[i]);  A[i] = i;  if(idx1[i] > idx2[i]) swap(idx1[i], idx2[i]);  }
    sort(A + 1, A + n , cmp);
    arr[n] = n;
    for(int i = n - 1;i >= 1; --i){
        int cur = A[i], pre = A[i - 1];  
        if(idx1[cur] == n || idx2[cur] != n) fail();
        if(idx1[cur] != idx1[pre]) 
        {
            arr[i] = idx1[cur];
            int a = idx1[pre] + 1, pos = i + 1;
            while(a < idx1[cur]) { if(!insert(a, pos)) fail(); ++a;  }
        }
    }
    for(int i = 1;i <= n; ++i) if(!arr[i]) fail();
    printf("YES\n");
    for(int i = 1;i < n; ++i) printf("%d %d\n",arr[i], arr[i + 1]);
    return 0;
}
posted @ 2018-10-09 16:25  EM-LGH  阅读(158)  评论(0编辑  收藏  举报