版权声明:转载请注明出处 https://blog.csdn.net/qq_41593522/article/details/84196495
题意
从1出发,遍历一棵树,使dfs序最小
可能有n条边
题解
贪心,每次向最小的节点走
调试记录
被卡常。
#include <cstdio>
#include <queue>
#include <vector>
#include <cstring>
#include <algorithm>
#define maxn 5005
using namespace std;
struct Enode{
int u, v;
}e[maxn];
//result node
struct ResNode{
int res[maxn], cnt;
void reset(){
cnt = 0;
memset(res, 0, sizeof res);
}
bool operator <(ResNode x)const{
for (int i = 1; i <= cnt; i++)
if (res[i] < x.res[i]) return true;
else if (res[i] > x.res[i]) return false;
return false;
}
ResNode operator =(ResNode x){
for (int i = 1; i <= cnt; i++)
res[i] = x.res[i];
cnt = x.cnt;
return *this;
}
}res, ans;
//find way
vector <int> E[maxn];
int n, m;
bool vis[maxn], tag[maxn << 1], flag;
void dfs(int cur, int u1, int v1){
if (res.cnt >= n) return;
if (vis[cur]) return;
vis[cur] = true;
if (cur > ans.res[res.cnt + 1] && !flag) return;
else if (cur < ans.res[res.cnt + 1]) flag = true;
res.res[++res.cnt] = cur;
for (int i = 0; i < E[cur].size(); i++){
if (cur == u1 && E[cur][i] == v1) continue;
if (cur == v1 && E[cur][i] == u1) continue;
if (!vis[E[cur][i]]) dfs(E[cur][i], u1, v1);
}
}
int main(){
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; i++){
scanf("%d%d", &e[i].u, &e[i].v);
E[e[i].u].push_back(e[i].v), E[e[i].v].push_back(e[i].u);
}
for (int i = 1; i <= n; i++) sort(E[i].begin(), E[i].end());
if (m == n - 1){
for (int i = 1; i <= n; i++)
ans.res[i] = n - i + 1;
res.reset();
dfs(1, 0, 0);
for (int i = 1; i <= n; i++)
printf("%d ", res.res[i]);
putchar('\n');
}
if (m == n){
for (int i = 1; i <= n; i++)
ans.res[i] = n - i + 1;
ans.cnt = n;
for (int i = 1; i <= n; i++){
flag = false;
memset(vis, false, sizeof vis);
res.reset();
dfs(1, e[i].u, e[i].v);
if (res.cnt == n){
if (res < ans) ans = res;
}
}
for (int i = 1; i <= n; i++)
printf("%d ", ans.res[i]);
putchar('\n');
}
return 0;
}