• 【NOIP模拟】树


    题面

    这道题目非常简单,由于是水题信心赛嘛,我就不多废话了。给定一棵树,每一条边连接着树上的两个点集 ,我们让这条边的魔法值为二元组 表示这两个集合中的数的最大值 (你可以认为,就是点编号的最大值)。

    好像是很简单的树p呢~
    那就请你来做这道题吧!欢乐送分
    不过,在比赛开始前 秒,我们一不小心搞丢了这道题的输入数据。 但是,万幸的是,输出数据还在。我们请
    你根据输出数据恢复这棵可怜的树

    分析

    又是一道构造,醉了。

    因为前面那道据说送分但是无人AC让我没时间想这个题,直接输出NO走人,25分到手(血赚,前面那个题输NO只有5分23333)

    其实血亏,私以为这道构造比第一道简单

    好吧,还是那句话 构造题==钻空子

    题让你构造树就真的构造树啊!!构造链啊!!(其实也有构造菊花图的)

    首先你必须发现,给出的一组点对中,其中有一个点必然是n(显然),如果不是n,就是无答案

    而我们用每个点对去除n后剩的数字构成一个序列。从小到大处理这个序列,查到每个在序列中的元素。

    当前查到在序列的元素有多个,就把不在序列里且比这个元素小的点和这个元素连边。

    因为是从小到大在连边,所以比前一个点大但是比当前元素小的左右两端点不会改变。

    最后再连上n这个点就OK了

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define N 5000
    int a,b,n,cnt,vis[N];
    struct email{int u,v;}e[N*4];
    inline void add(int u,int v){e[++cnt].u=u,e[cnt].v=v;}
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&a,&b);
            if(a>b)swap(a,b);
            if(b!=n||a==b){puts("NO");return 0;}
            vis[a]++;
        }
        for(int i=1;i<n;i++)
        {
            if(vis[i]>1)
            {
                int last=i;
                for(int j=1;j<i;j++)
                    if(!vis[j])
                    {
                        vis[j]++;vis[i]--;
                        add(j,last);last=j;
                        if(vis[i]==1)break;
                    }
                if(vis[i]==1)add(last,n);
                else {puts("NO");return 0;}
            }
            else if(vis[i]==1)add(i,n);
        }
        puts("YES");
        for(int i=1;i<=cnt;i++)printf("%d %d
    ",e[i].u,e[i].v);
        return 0;
    }
  • 相关阅读:
    GUI线程安全详解(二)
    如何用BlazeDS前后台数据交互
    定制Flex菜单图标
    Web App第三方组件PKDashcode&Sencha
    如何用BlazeDS更改图片
    GUI线程安全详解(一)
    Flex Spark皮肤定制
    GUI线程安全详解(三)
    (C# 基础) Array ( Copy, Clone, Clear etc.)
    System.ArgumentException: Destination array was not long enough.
  • 原文地址:https://www.cnblogs.com/NSD-email0820/p/9886045.html
Copyright © 2020-2023  润新知