zoukankan      html  css  js  c++  java
  • AGC Tree Restoring 题解

    题目连接

    Tree Restoring

    青木君很喜欢数列和树。

    一天,高桥君给了他一个长度为 \(N\) 的数列 \(a1, a2, …, aN\),这让青木有了构造一棵树的冲动。

    他想要构造一棵树,其中 \(i\) 号点与其它点的树上距离的最大值恰好等于 \(ai\)(假设树边长度均为\(1\))。

    请问是否存在这样一棵树符合要求。

    sol

    这种题目可以从极端情况入手,而这里的极端就是树的直径。

    • 因为任何树都存在至少一条直径,所以一定存在一对相等且最大的 \(a[u]\)\(a[v]\) ,其中 \(u\)\(v\) 是直径的两端,如果不存在,输出 \(Impossible\)

    • 找到直径后,直径上的所有点的 \(a[i]\) 都可以推出,如果给出的 \(a\) 序列中找不到对应的值,输出 \(Impossible\)

    • 接下来,其余点都相当于挂在直径这条链的两侧(不允许挂在 \(u\)\(v\) 上,否则直径会更长)。显然,如果这些点的 \(a[i]\) 值没有大于直径的一半(向上取整),我们把这个长度设为 \(mid\) ,那么他显然不可以出现在链上,所以输出 \(Impossible\);否则,一定可以构造出符合条件的悬挂方式:由于剩余点的 \(a[i]∈[mid+1,a[u]]\) ,所以一定可以在直径上找到一个距离 \(u\)\(v\) 恰好为 \(a[i]-1\) 的点 \(x\),将 \(i\)\(x\) 连接,使得 \(a[i]\) 符合要求。由于新加的边长度都为 \(1\) ,不会使链变长。

    code

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+5;
    int N,cnt[maxn],a[maxn];
    inline int read(){
    	int ret=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
    	while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar();
    	return ret*f;
    }
    int main(){
    	freopen("Half Reflector.in","r",stdin);
    	freopen("Half Reflector.out","w",stdout);
    	N=read();
    	for(int i=1;i<=N;i++) cnt[a[i]=read()]++;
    	sort(a+1,a+1+N);
    	if(a[N-1]!=a[N]) return printf("Impossible\n"),0;
    	cnt[a[N]]-=2;
    	for(int i=1;i<a[N];i++){
    		int d=max(i,a[N]-i);
    		if(cnt[d]<1) return printf("Impossible\n"),0;
    		cnt[d]--;
    	}
    	for(int i=1;i<=(a[N]+1>>1);i++)if(cnt[i]) return printf("Impossible\n"),0;
    	printf("Possible\n");
    	return 0;
    }
    
  • 相关阅读:
    关于故事和段子
    SQLserver2008数据库备份和还原问题(还原是必须有完整备份)
    百度文库破解方法
    如何识别病毒,转自百度文库,千辛万苦破解出来的
    20个人艰不拆的事实:知道真相的我眼泪掉下来 T.T
    linux学习网站分享
    个人对于腾讯和优酷的看法
    今天去客户现场的一些感想
    基于 Blazui 的 Blazor 后台管理模板 Blazui.Admin 正式尝鲜
    新手福利!Blazor 从入门到砖家系列教程(你真的可以成为砖家)
  • 原文地址:https://www.cnblogs.com/martian148/p/15532291.html
Copyright © 2011-2022 走看看