题意:假定我们已知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; }