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;
}

猜你喜欢

转载自www.cnblogs.com/acm1ruoji/p/10771392.html