判了走完整个环的情况,代码下方那三个小范围的 hack 都过了,88pts 求调
#include <bits/stdc++.h>
using namespace std;
namespace lgh {
#define int long long
#define pii pair<int, int>
const int N = 5e5 + 5;
const int INF = 0x3f3f3f3f;
int n, m;
struct Edge {
int to, pre;
};
Edge e[N * 2];
int idx = 1, head[N];
void addedge(int u, int v) {
e[++idx] = {v, head[u]};
head[u] = idx;
}
bool edgecut[N * 2];
int dfn[N], low[N], index;
bool instk[N];
void tarjan(int u, int lst) {
dfn[u] = low[u] = ++index;
instk[u] = 1;
for(int i = head[u]; i; i = e[i].pre) {
int v = e[i].to;
if(v == lst) continue;
if(!dfn[v]) {
tarjan(v, u);
low[u] = min(low[u], low[v]);
if(low[v] > dfn[u]) {
edgecut[i] = edgecut[i ^ 1] = 1;
}
} else if(instk[v]) {
low[u] = min(low[u], dfn[v]);
}
}
instk[u] = 0;
}
vector<int> ans;
bool vis[N];
int rec;
pii get(int u) {
pii res;
for(int i = head[u]; i; i = e[i].pre) {
if(edgecut[i]) continue;
int v = e[i].to;
if(vis[v]) continue;
if(!res.first) res.first = v;
else res.second = v;
}
if(res.second && res.first > res.second) swap(res.first, res.second);
return res;
}
void dfs(int u) {
ans.push_back(u);
pii t = get(u);
if(!t.first) { // 当前点不在环上
vector<int> son;
for(int i = head[u]; i; i = e[i].pre) {
int v = e[i].to;
if(vis[v]) continue;
son.push_back(v);
}
sort(son.begin(), son.end());
for(auto &v : son) {
vis[v] = 1;
dfs(v);
}
return;
}
if(t.second) { // 当前点是关键点
vector<int> son;
int tar = t.first;
rec = t.second;
// printf("keyp %lld %lld %lld\n", u, tar, rec);
for(int i = head[u]; i; i = e[i].pre) {
int v = e[i].to;
if(vis[v]) continue;
if(v >= tar) continue;
son.push_back(v);
}
sort(son.begin(), son.end());
for(auto &v : son) {
vis[v] = 1;
dfs(v);
}
vis[tar] = 1;
dfs(tar);
son.clear();
for(int i = head[u]; i; i = e[i].pre) {
int v = e[i].to;
if(vis[v]) continue;
if(v >= rec) continue;
son.push_back(v);
}
sort(son.begin(), son.end());
for(auto &v : son) {
vis[v] = 1;
dfs(v);
}
// puts("------------------------");
if(!vis[rec]) {
vis[rec] = 1;
int tmp = rec;
rec = INF;
dfs(tmp);
}
son.clear();
for(int i = head[u]; i; i = e[i].pre) {
int v = e[i].to;
if(vis[v]) continue;
son.push_back(v);
}
sort(son.begin(), son.end());
for(auto &v : son) {
vis[v] = 1;
dfs(v);
}
return;
}
vector<int> son;
int tar = t.first;
for(int i = head[u]; i; i = e[i].pre) {
int v = e[i].to;
if(vis[v]) continue;
if(v >= tar) continue;
son.push_back(v);
}
sort(son.begin(), son.end());
for(auto &v : son) {
vis[v] = 1;
dfs(v);
}
if(tar <= rec) {
vis[tar] = 1;
dfs(tar);
}
// else printf("stop %lld %lld\n", u, tar);
son.clear();
for(int i = head[u]; i; i = e[i].pre) {
int v = e[i].to;
if(vis[v]) continue;
if(v == tar) continue;
son.push_back(v);
}
sort(son.begin(), son.end());
for(auto &v : son) {
vis[v] = 1;
dfs(v);
}
}
signed main() {
scanf("%lld %lld", &n, &m);
for(int i = 1; i <= m; ++i) {
int u, v;
scanf("%lld %lld", &u, &v);
addedge(u, v);
addedge(v, u);
}
tarjan(1, 0);
vis[1] = 1;
dfs(1);
for(auto &i : ans) printf("%lld ", i);
return 0;
}
}
signed main() {
// freopen("travel.in", "r", stdin);
// freopen("travel.out", "w", stdout);
return lgh::main();
}
/*
hack1:
6 6
1 2
1 3
1 4
1 5
1 6
2 3
ans1:
1 2 3 4 5 6
hack2:
9 9
1 6
1 2
2 9
2 3
2 7
3 4
3 8
4 5
5 7
ans2:
1 2 3 4 5 7 8 9 6
hack3:
5 5
1 2
2 3
3 4
4 2
3 5
ans3:
1 2 3 4 5
*/