1152E - Neko and Flashback

题意:对于长为n的序列c和长为n - 1的排列p,我们可以按照如下方法得到长为n - 1的序列a,b,a',b'。

ai = min(ci, ci+1),bi = max(ci, ci+1)

a'i = ap[i],b'i = bp[i]

现在给定a'和b',求一个合法的c或者无解。

解:仔细分析性质,发现在a和b中,c除了开头和结尾会出现1次之外,每个数都会出现两次,且相邻。

我们可以把c的开头找出来,然后根据开头确定c2,然后确定c3...最后到cn

注意到这些数可能有重复的,于是我们要试图在中间插入一段。我一开始想的是链表后来发现很难写...

仔细分析,如果把a'和b'的每个位置当成边,数字当成点,就是求欧拉路。然后就没了......

关于欧拉路:就暴力DFS,把每条边都访问一次。回溯的时候把这条边入栈/把y入栈。

 #include <bits/stdc++.h>

 const int N = ;

 struct Edge {
int nex, v, id, pre;
}edge[N << ]; int tp = ; int X[N], xx, a[N], b[N], cnt[N], e[N], stk[N], top, deg[N];
bool vis[N]; inline void erase(int x, int i) {
int nex = edge[i].nex, pre = edge[i].pre;
if(e[x] == i && !nex) {
e[x] = ;
}
else if(e[x] == i) {
e[x] = nex;
edge[nex].pre = ;
return;
}
else if(!nex) {
edge[pre].nex = ;
}
else {
edge[nex].pre = pre;
edge[pre].nex = nex;
}
edge[i].nex = edge[i].pre = ;
return;
} inline void add(int x, int y, int z) {
edge[++tp].v = y;
edge[tp].id = z;
edge[tp].nex = e[x];
edge[e[x]].pre = tp;
e[x] = tp;
return;
} void DFS(int x) {
for(int i = e[x]; i; i = edge[i].nex) {
erase(x, i);
int y = edge[i].v;
if(vis[edge[i].id]) {
continue;
}
vis[edge[i].id] = ;
DFS(y);
stk[++top] = y;
}
return;
} int main() { int n;
scanf("%d", &n);
for(int i = ; i < n; i++) {
scanf("%d", &a[i]);
X[++xx] = a[i];
}
for(int j = ; j < n; j++) {
scanf("%d", &b[j]);
X[++xx] = b[j];
if(b[j] < a[j]) {
puts("-1");
return ;
}
} std::sort(X + , X + xx + );
xx = std::unique(X + , X + xx + ) - X - ;
for(int i = ; i < n; i++) {
a[i] = std::lower_bound(X + , X + xx + , a[i]) - X;
b[i] = std::lower_bound(X + , X + xx + , b[i]) - X;
add(a[i], b[i], i);
add(b[i], a[i], i);
deg[a[i]]++;
deg[b[i]]++;
}
int s = , pos = ;
for(int i = ; i <= xx; i++) {
if(deg[i] & ) {
s++;
pos = i;
}
}
if(s != && s != ) {
puts("-1");
return ;
} DFS(pos);
stk[++top] = pos;
if(top != n) {
puts("-1");
return ;
}
for(int i = top; i >= ; i--) {
printf("%d ", X[stk[i]]);
} return ;
}

AC代码

注意复杂度,删边......

 #include <bits/stdc++.h>

 const int N = ;

 struct Edge {
int nex, v, id;
}edge[N << ]; int tp = ; int X[N], xx, a[N], b[N], cnt[N], e[N], stk[N], top, deg[N];
bool vis[N]; inline void add(int x, int y, int z) {
edge[++tp].v = y;
edge[tp].id = z;
edge[tp].nex = e[x];
e[x] = tp;
return;
} void DFS(int x) {
for(int i = e[x]; i; i = e[x]) {
e[x] = edge[i].nex;
int y = edge[i].v;
if(vis[edge[i].id]) {
continue;
}
vis[edge[i].id] = ;
DFS(y);
stk[++top] = y;
}
return;
} int main() { int n;
scanf("%d", &n);
for(int i = ; i < n; i++) {
scanf("%d", &a[i]);
X[++xx] = a[i];
}
for(int j = ; j < n; j++) {
scanf("%d", &b[j]);
X[++xx] = b[j];
if(b[j] < a[j]) {
puts("-1");
return ;
}
} std::sort(X + , X + xx + );
xx = std::unique(X + , X + xx + ) - X - ;
for(int i = ; i < n; i++) {
a[i] = std::lower_bound(X + , X + xx + , a[i]) - X;
b[i] = std::lower_bound(X + , X + xx + , b[i]) - X;
add(a[i], b[i], i);
add(b[i], a[i], i);
deg[a[i]]++;
deg[b[i]]++;
}
int s = , pos = ;
for(int i = ; i <= xx; i++) {
if(deg[i] & ) {
s++;
pos = i;
}
}
if(s != && s != ) {
puts("-1");
return ;
} DFS(pos);
stk[++top] = pos;
if(top != n) {
puts("-1");
return ;
}
for(int i = top; i >= ; i--) {
printf("%d ", X[stk[i]]);
} return ;
}

另一种删边方式

[欧拉路]CF1152E Neko and Flashback的更多相关文章

  1. 洛谷P1341 无序字母对[无向图欧拉路]

    题目描述 给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒).请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现. 输入输出格式 输入格式: 第一行输入一 ...

  2. POJ1386Play on Words[有向图欧拉路]

    Play on Words Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11846   Accepted: 4050 De ...

  3. hdu1161 欧拉路

    欧拉路径是指能从一个点出发能够“一笔画”完整张图的路径:(每条边只经过一次而不是点) 在无向图中:如果每个点的度都为偶数 那么这个图是欧拉回路:如果最多有2个奇数点,那么出发点和到达点必定为该2点,那 ...

  4. UVA10054The Necklace (打印欧拉路)

    题目链接 题意:一种由彩色珠子组成的项链.每个珠子的两半由不同的颜色组成.相邻的两个珠子在接触的地方颜色相同.现在有一些零碎的珠子,需要确定他们是否可以复原成完整的项链 分析:之前也没往欧拉路上面想, ...

  5. 洛谷 P1341 无序字母对 Label:欧拉路 一笔画

    题目描述 给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒).请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现. 输入输出格式 输入格式: 第一行输入一 ...

  6. POJ 1637 Sightseeing tour (混合图欧拉路判定)

    Sightseeing tour Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6986   Accepted: 2901 ...

  7. hihocoder 1181 欧拉路.二

    传送门:欧拉路·二 #1181 : 欧拉路·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在上一回中小Hi和小Ho控制着主角收集了分散在各个木桥上的道具,这些道具其 ...

  8. hiho48 : 欧拉路·一

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho最近在玩一个解密类的游戏,他们需要控制角色在一片原始丛林里面探险,收集道具,并找到最后的宝藏.现在他们控制的 ...

  9. hdu5883 The Best Path(欧拉路)

    题目链接:hdu5883 The Best Path 比赛第一遍做的时候没有考虑回路要枚举起点的情况导致WA了一发orz 节点 i 的贡献为((du[i] / 2) % 2)* a[i] 欧拉回路的起 ...

随机推荐

  1. 【JZOJ6274】梦境

    description analysis 其实可以贪心 先把区间按左端点排序,转折点也排序 扫一次转折点,把所有左端点在当前点左边的区间丢进优先队列里 按照贪心策略,对于某个转折点,一定选择右端点离它 ...

  2. CSS压缩

    通过W3C 统一验证工具的检测没有错误后,为了提高加载速度和节约空间(相对来说,css量很少的情况下,几乎没啥区别),可以通过css压缩工具把css进行压缩. w3c css压缩 http://too ...

  3. 模拟MySQL命令

    staff_table 1,Alex Li,22,13651054608,IT,2013-04-01 2,Jack Wang,30,13304320533,HR,2015-05-03 3,Rain L ...

  4. C++Builder中注册表的操作

    僮骶头浅5募虻チ耍旅嫖揖鸵砸桓鍪道此得鱐Registry类的用法.首先,先介绍一下TRegistry的属性和方法:TRegistry类一共有四个属性.属性 类型 描述CurrentKey int ...

  5. CF1086F Forest Fires

    CF1086F Forest Fires 有点意思的题目 直接统计每个格子的val是非常难办的.很难知道每秒新出来多少个格子 设$F[i]$表示,前i时刻覆盖的格子的数量 则,$ans=\sum_{i ...

  6. 【题解】洛谷 P1061 Jam的计数法

    #include <iostream> #include <cstring> #include <cstdio> using namespace std; int ...

  7. SPSS分类分析:决策树

    SPSS分类分析:决策树 一.决策树(分析-分类-决策树) "决策树"过程创建基于树的分类模型.它将个案分为若干组,或根据自变量(预测变量)的值预测因变量(目标变量)的值.此过程为 ...

  8. Python机器学习的步骤

    原文出处: kdnuggets   译文出处:数据工匠 开始.这是最容易令人丧失斗志的两个字.迈出第一步通常最艰难.当可以选择的方向太多时,就更让人两腿发软了. 从哪里开始? 本文旨在通过七个步骤,使 ...

  9. import time 进度条动态输出26个字母

    # 2018-08-06 19:42:51 import time # 调用时间模块 num = 97 # 字母a while num <= 115: # print(chr(num), end ...

  10. 面试系列26 如何基于dubbo进行服务治理、服务降级、失败重试以及超时重试

    (1)服务治理 1)调用链路自动生成 一个大型的分布式系统,或者说是用现在流行的微服务架构来说吧,分布式系统由大量的服务组成.那么这些服务之间互相是如何调用的?调用链路是啥?说实话,几乎到后面没人搞的 ...