• E. Neko and Flashback


    传送门:

    题意:假定我们已知a[]={3,4,6,5,7},  那么b[]通过min(a[i],a[i+1])得到 那么b[]={3,4,5,5}, c[]通过max(a[i],a[i+1])得到 c[]={4,6,6,7},然后还有个p数组  p[]={2,4,1,3}

    之后我们通过b1[i]=b[p[i]],得到b1[]={4,5,3,5},同理 c1[]={6,7,4,6}

    现在题目给出 b1,c1数组的值,让我们求出a数组,因为b1,c1都是根据p数组由b,c数组变换来的,所以b,c相对位置是没有改变的。那么我们把最小值跟最大值连成一条边,也就是说把b1[i],c1[i]连城边,最后问题就转换成求这堆线的欧拉通路

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define re register
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define P pair<int,int>
    const int N=1e6+10;
    void read(int &a)
    {
        a=0;
        int d=1;
        char ch;
        while(ch=getchar(),!isdigit(ch))
            if(ch=='-')
                d=-1;
        a=ch^48;
        while(ch=getchar(),isdigit(ch))
            a=(a<<3)+(a<<1)+(ch^48);
        a*=d;
    }
    void write(int x)
    {
        if(x<0)
            putchar(45),x=-x;
        if(x>9)
            write(x/10);
        putchar(x%10+'0');
    }
    int num,w[N<<1],tot,head[N<<1],a[N],b[N],du[N],ans[N<<1],vis[N],m;
    map <int,int> id;
    struct note
    {
        int v,next;
    }edge[N<<1];
    int getv(int x)
    {
        if(!id[x])///离散化,给每个值一个编号
            w[id[x]=++tot]=x;
        return id[x];
    }
    void add(int u,int v)
    {
        edge[++num].v=v;
        edge[num].next=head[u];
        head[u]=num;
        du[u]++;
        edge[++num].v=u;
        edge[num].next=head[v];
        head[v]=num;
        du[v]++;p
    }
    void dfs(int u)
    {
        for(int &i=head[u];i;i=edge[i].next)
            if(!vis[i>>1])///无向边每条边只能走一次,所以标记是这条边编号除2
                vis[i>>1]=1,dfs(edge[i].v);
        ans[++m]=u;
    }
    int main()
    {
        int n;
        read(n);
        for(re int i=1;i<n;i++)
            read(a[i]);
        for(re int i=1;i<n;i++)
            read(b[i]);
        num++;///控制后面加边的操作保证/2得到的是同一条边
        for(re int i=1;i<n;i++)
        {
            if(a[i]>b[i])///当b[i]>c[i]时说明不成立,显而易见的emmm
                return puts("-1"),0;
            add(getv(a[i]),getv(b[i]));
        }
        int s=1,sum=0;
        for(re int i=1;i<=tot;i++)
            if(du[i]&1)
                sum++,s=i;///起点只能是度数是奇数的点,没有的话就从1开始把--
        if(sum&&sum!=2)///欧拉通路中,最多只能有两个点是度数为奇数的点,而且这两个点分别作为起点和终点
            return puts("-1"),0;
        dfs(s);
        if(m-n)
            return puts("-1"),0;
        for(re int i=1;i<=n;i++)
            write(w[ans[i]]),putchar(' ');
        return 0;
    }
  • 相关阅读:
    微信小程序 editor富文本
    vuex详解
    每日一练
    如何有效地进行代码 Review?
    vue实现瀑布流
    浅谈js防抖和节流-转载
    Java Kafka 消费积压监控
    用于文本内容的复制粘贴
    Java 键值对数据本地保存与读取
    Java ElasticSearch 操作
  • 原文地址:https://www.cnblogs.com/acm1ruoji/p/10771392.html
Copyright © 2020-2023  润新知