[欧拉路]CF1152E Neko and Flashback

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入栈。

  1 #include <bits/stdc++.h>
  2 
  3 const int N = 200010;
  4 
  5 struct Edge {
  6     int nex, v, id, pre;
  7 }edge[N << 1]; int tp = 1;
  8 
  9 int X[N], xx, a[N], b[N], cnt[N], e[N], stk[N], top, deg[N];
 10 bool vis[N];
 11 
 12 inline void erase(int x, int i) {
 13     int nex = edge[i].nex, pre = edge[i].pre;
 14     if(e[x] == i && !nex) {
 15         e[x] = 0;
 16     }
 17     else if(e[x] == i) {
 18         e[x] = nex;
 19         edge[nex].pre = 0;
 20         return;
 21     }
 22     else if(!nex) {
 23         edge[pre].nex = 0;
 24     }
 25     else {
 26         edge[nex].pre = pre;
 27         edge[pre].nex = nex;
 28     }
 29     edge[i].nex = edge[i].pre = 0;
 30     return;
 31 }
 32 
 33 inline void add(int x, int y, int z) {
 34     edge[++tp].v = y;
 35     edge[tp].id = z;
 36     edge[tp].nex = e[x];
 37     edge[e[x]].pre = tp;
 38     e[x] = tp;
 39     return;
 40 }
 41 
 42 void DFS(int x) {
 43     for(int i = e[x]; i; i = edge[i].nex) {
 44         erase(x, i);
 45         int y = edge[i].v;
 46         if(vis[edge[i].id]) {
 47             continue;
 48         }
 49         vis[edge[i].id] = 1;
 50         DFS(y);
 51         stk[++top] = y;
 52     }
 53     return;
 54 }
 55 
 56 int main() {
 57     
 58     int n;
 59     scanf("%d", &n);
 60     for(int i = 1; i < n; i++) {
 61         scanf("%d", &a[i]);
 62         X[++xx] = a[i];
 63     }
 64     for(int j = 1; j < n; j++) {
 65         scanf("%d", &b[j]);
 66         X[++xx] = b[j];
 67         if(b[j] < a[j]) {
 68             puts("-1");
 69             return 0;
 70         }
 71     }
 72     
 73     std::sort(X + 1, X + xx + 1);
 74     xx = std::unique(X + 1, X + xx + 1) - X - 1;
 75     for(int i = 1; i < n; i++) {
 76         a[i] = std::lower_bound(X + 1, X + xx + 1, a[i]) - X;
 77         b[i] = std::lower_bound(X + 1, X + xx + 1, b[i]) - X;
 78         add(a[i], b[i], i);
 79         add(b[i], a[i], i);
 80         deg[a[i]]++;
 81         deg[b[i]]++;
 82     }
 83     int s = 0, pos = 1;
 84     for(int i = 1; i <= xx; i++) {
 85         if(deg[i] & 1) {
 86             s++;
 87             pos = i;
 88         }
 89     }
 90     if(s != 0 && s != 2) {
 91         puts("-1");
 92         return 0;
 93     }
 94     
 95     DFS(pos);
 96     stk[++top] = pos;
 97     if(top != n) {
 98         puts("-1");
 99         return 0;
100     }
101     for(int i = top; i >= 1; i--) {
102         printf("%d ", X[stk[i]]);
103     }
104     
105     return 0;
106 }
AC代码

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

 1 #include <bits/stdc++.h>
 2 
 3 const int N = 200010;
 4 
 5 struct Edge {
 6     int nex, v, id;
 7 }edge[N << 1]; int tp = 1;
 8 
 9 int X[N], xx, a[N], b[N], cnt[N], e[N], stk[N], top, deg[N];
10 bool vis[N];
11 
12 inline void add(int x, int y, int z) {
13     edge[++tp].v = y;
14     edge[tp].id = z;
15     edge[tp].nex = e[x];
16     e[x] = tp;
17     return;
18 }
19 
20 void DFS(int x) {
21     for(int i = e[x]; i; i = e[x]) {
22         e[x] = edge[i].nex;
23         int y = edge[i].v;
24         if(vis[edge[i].id]) {
25             continue;
26         }
27         vis[edge[i].id] = 1;
28         DFS(y);
29         stk[++top] = y;
30     }
31     return;
32 }
33 
34 int main() {
35     
36     int n;
37     scanf("%d", &n);
38     for(int i = 1; i < n; i++) {
39         scanf("%d", &a[i]);
40         X[++xx] = a[i];
41     }
42     for(int j = 1; j < n; j++) {
43         scanf("%d", &b[j]);
44         X[++xx] = b[j];
45         if(b[j] < a[j]) {
46             puts("-1");
47             return 0;
48         }
49     }
50     
51     std::sort(X + 1, X + xx + 1);
52     xx = std::unique(X + 1, X + xx + 1) - X - 1;
53     for(int i = 1; i < n; i++) {
54         a[i] = std::lower_bound(X + 1, X + xx + 1, a[i]) - X;
55         b[i] = std::lower_bound(X + 1, X + xx + 1, b[i]) - X;
56         add(a[i], b[i], i);
57         add(b[i], a[i], i);
58         deg[a[i]]++;
59         deg[b[i]]++;
60     }
61     int s = 0, pos = 1;
62     for(int i = 1; i <= xx; i++) {
63         if(deg[i] & 1) {
64             s++;
65             pos = i;
66         }
67     }
68     if(s != 0 && s != 2) {
69         puts("-1");
70         return 0;
71     }
72     
73     DFS(pos);
74     stk[++top] = pos;
75     if(top != n) {
76         puts("-1");
77         return 0;
78     }
79     for(int i = top; i >= 1; i--) {
80         printf("%d ", X[stk[i]]);
81     }
82     
83     return 0;
84 }
另一种删边方式

 

posted @ 2019-06-01 10:19  huyufeifei  阅读(207)  评论(0编辑  收藏  举报
试着放一个广告栏(虽然没有一分钱广告费)

『Flyable Heart 応援中!』 HHG 高苗京铃 闪十PSS 双六 電動伝奇堂 章鱼罐头制作组 はきか 祝姬 星降夜