CF1152E

这题题目有点问题,应该是 (b_i=min{a_i,a_{i+1}})(c_i) 同理。
不过没什么影响。


根据题目可以发现,(b_i)(a_i,a_{i+1}) 中较小的那个,而 (c_i) 是较大的。

所以 (b_i>c_i) 时无解。

观察一下样例,可以发现答案就是从某个数开始取,再取另一个序列中的同位置的数,然后转到这个同位置数的另一个出现位置,重复上述操作。

所以我们要找从哪个数开始取。

我们要保证每个数都被取一次,而且是按上述方式不间断地取。

可以发现这个过程类似于找欧拉路径的过程。

那我们对于每一对 ((b_i,c_i)(iin[1,n-1])) 连无向边,然后按找欧拉路径的方法判断一下有无解以及起点,最后输出即可。

bool flag,vis[maxn];
int n,cnt,m,top,st,_js;
int du[maxn],base[maxn],c[maxn];
int zhan[maxn],d[maxn],a[maxn],b[maxn];
struct node{int pos,num;};
vector<node> g[maxn];

void dfs(int u){
  for(int i=d[u];i<g[u].size();i=d[u]){
    d[u]++;node to=g[u][i];
    if(vis[to.num]) continue;
    vis[to.num]=1;dfs(to.pos);
  }
  zhan[++top]=u;
}

int main(){
  n=read();
  for(int i=1;i<n;i++) base[++cnt]=b[i]=read();
  for(int i=1;i<n;i++) base[++cnt]=c[i]=read();
  sort(base+1,base+cnt+1);
  int tot=unique(base+1,base+cnt+1)-base-1;
  for(int i=1;i<n;i++){
    b[i]=lower_bound(base+1,base+tot+1,b[i])-base;
    c[i]=lower_bound(base+1,base+tot+1,c[i])-base;
    if(b[i]>c[i]) return puts("-1"),0;
    int u=b[i],v=c[i];du[u]++;du[v]++;
    g[u].push_back((node){v,i});
    g[v].push_back((node){u,i});
  }
  for(int i=1;i<=tot;i++) _js+=(du[i]&1);
  if(_js&&_js!=2) return puts("-1"),0;
  if(!_js) dfs(1);
  else for(int i=1;i<=tot;i++) 
    if(du[i]&1){dfs(i);break;}
  if(top^n)return puts("-1"),0;
    for(int i=top;i>=1;i--)
      printf("%d ",base[zhan[i]]);
  return 0;
}
原文地址:https://www.cnblogs.com/KnightL/p/15228091.html