• 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;
    }
    
  • 相关阅读:
    Nubia Z5S官方4.4 UI2.0音频Audio部分简单分析(也适用于其它8974/8064机型)以及降低破音出现几率的方法
    import MySQLdb UserWarning
    Visual Studio 2013 Update2
    cocos2d 重写顶点着色语言
    tomcat之组成结构
    4、Android Activity的生命周期 Activity的生命周期
    学习中遇到的c++问题,持续更新
    Android开发之发送邮件功能的实现(源码分享)
    Java 类型, Hibernate 映射类型及 SQL 类型之间的相应关系
    QT内label控件通过opencv显示图像
  • 原文地址:https://www.cnblogs.com/martian148/p/15532291.html
Copyright © 2020-2023  润新知