CF36E Two Paths 题解
分类讨论:设连通块数量为 $c$,奇数点数量为 $s$。
- $c > 2$ 时,不珂学。
- $c = 2$ 时,两个连通块分别跑欧拉路径。
- $c = 1$ 时,再分讨:
- $s \not = 0,2,4$ 不珂学。
- $s = 0,2$ 跑一遍欧拉路径。
- $s = 4$ 连一条虚边, 跑一遍欧拉路径。
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4 + 500;
struct edge{
int next, to, w, id;
} e[N << 1];
int n, m;
int head[N], cnt = 1;
void add(int f, int t, int i) {
e[++cnt] = edge{head[f], t, 1, i}, head[f] = cnt;
e[++cnt] = edge{head[t], f, 1, i}, head[t] = cnt;
}
vector<int> SCC[N];
int du[N], tot, d[N], r_in[N];
int st[N], top;
void pre_dfs(int u, int f) {
if(!d[u]) SCC[tot].emplace_back(u);
d[u] = tot;
for(int i = head[u];i;i = e[i].next) {
int v = e[i].to;
if(v == f || d[v]) continue;
pre_dfs(v, u);
}
}
void dfs(int u) {
for(int &i = head[u]; i; i = e[i].next) {
int v = e[i].to, id = e[i].id;
if(!e[i].w) continue;
e[i].w = e[i ^ 1].w = 0;
dfs(v);
st[++top] = id;
}
}
int main() {
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
ios::sync_with_stdio(0);
cin.tie(nullptr), cout.tie(nullptr);
n = 1e4;
cin >> m;
int R_a = 0, R_b = 0;
for(int i = 1; i <= m; ++i) {
int u, v;
cin >> u >> v;
if(!R_a) R_a = u, R_b = v;
add(u, v, i);
du[u]++, du[v]++;
r_in[u] = r_in[v] = 1;
}
for(int i = 1; i <= n; ++i) if(r_in[i] && !d[i]) ++tot, pre_dfs(i, 0);
// for(auto o : SCC[1]) cout << o << " "; cout << endl;
// for(int i = 1; i <= n; ++i) if(r_in[i]) cout << du[i] << " "; cout << endl;
if(tot >= 3) {cout << -1; return 0; }
else if(tot == 2) {
int id = SCC[1][0], cnt = 0;
int id2 = SCC[2][0], cnt2 = 0;
for(auto o : SCC[1])
if(du[o] & 1) {
id = o;
cnt++;
}
for(auto o : SCC[2])
if(du[o] & 1) {
id2 = o;
cnt2++;
}
if(cnt & 1 || cnt > 2) {cout << -1; return 0; }
if(cnt2 & 1 || cnt2 > 2) {cout << -1; return 0; }
dfs(id);cout << top << endl;
for(int i = 1; i <= top; ++i) cout << st[i] << " ";
cout << endl; top = 0;
dfs(id2); cout << top << endl;
for(int i = 1; i <= top; ++i) cout << st[i] << " ";
} else {
int id[5] = {0, 0, 0, 0, 0}, cnt = 0;
for(auto o : SCC[1]) {
if(du[o] & 1) {
cnt++; int j = 0;
while(j < 4 && id[++j]);
if(j <= 4 && !id[j]) id[j] = o;
}
}
if(cnt & 1 || cnt > 4) {cout << -1; return 0; }
if(!cnt || cnt == 2) {
if(cnt) dfs(id[1]);
else dfs(SCC[1][0]);
if(top == 1) {cout << -1; return 0; }
cout << top - 1 << endl;
for(int i = 1; i < top; ++i) cout << st[i] << " ";
cout << endl << 1 << endl << st[top];
} else {
add(id[1], id[2], 114514);
dfs(id[3]);
int j = 1;
vector<int> i1, i2;
for(; j <= top; ++j) if(st[j] != 114514) i1.emplace_back(st[j]); else break;
for(; j <= top; ++j) if(st[j] != 114514) i2.emplace_back(st[j]); // 这里可能有危险
cout << i1.size() << endl;
for(auto o : i1) cout << o << " ";
cout << endl << i2.size() << endl;
for(auto o : i2) cout << o << " ";
}
}
return 0;
}

浙公网安备 33010602011771号