#include <bits/stdc++.h>
using namespace std;
vector <int> G[10005];//vector邻接表存图
int f[5005],q=0,vis[5005],x,y,n,m,ux,uy,a[5005],flag=0,loop_num[5005],p = 0;
void dfs(int x){//m==n-1的情况,因为我后面把vecotr排了序,所以dfs第一遍跑出来的就是最优解
f[++q] = x;
for(int i = 0; i < G[x].size(); ++i)
if(!vis[G[x][i]]) {
int y = G[x][i];
vis[y] = 1;
dfs(y);
}
}
void find_loop(int x,int root,int fa){//找出在环内的点
loop_num[++p] = x;
if(flag) return;
for(int i = 0; i < G[x].size(); ++i){
int y = G[x][i];
if(y==fa) continue;
if(vis[y]&&y==root) {
flag = 1;
return;
}
if(!vis[y]){
vis[y] = 1;
find_loop(y,root,x);
vis[y] = 0;
if(flag) return;
}
}
if(!flag) p--;
}
void dfs1(int x){//情况二,就是枚举删掉环内的边来找到删完边后的当前最优解
a[++q] = x;
//printf("%d %d ",a[q],x);
for(int i = 0; i < G[x].size(); ++i){
int y = G[x][i];
if((x==ux&&y==uy)||(x==uy&&y==ux)) continue;
if(!vis[y]){
vis[y] = 1;
dfs(y);
//printf("%d ",y);
}
}
}
void choseans(){//拿当前最优解和已知最优解比较大小,更新
int bj = 0;
for(int i = 1; i <= n; ++i){
if(a[i] < f[i]) {
bj = 1;
break;
}else if(a[i]>f[i]) break;
}
if(bj)
for(int i = 1; i <= n; ++i){
f[i] = a[i];
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i = 1; i <= m; ++i){
scanf("%d%d",&x,&y);
G[x].push_back(y);
G[y].push_back(x);
}//无向边存图
for(int i = 1; i <= n; ++i)//vector排序
sort(G[i].begin(),G[i].end());
vis[1] = 1;
dfs(1);//先跑一遍找出可行解,使f数组有值可比较
if(m==n-1){//这种情况的话那这个可行解就是最优解
for(int i = 1; i <= n; ++i) printf("%d ",f[i]);
}else if(m==n){
flag = 0;//flag=1表示已找到环
//找出环内点
for(int i = 1; i <= n; ++i){//1到n个点尝试把每个点都作为环的起点(或者根节点)开始跑树
memset(vis,0,sizeof(vis));//清零 vis[i] = 1;
if(!flag) {
p = 0;
find_loop(i,i,-1);//分别代入当前点,起点,当前点的父节点(无向图的起点无父节点所以代-1进去)。
}
}//上面得出一个长度为p的数组loop_num[],里面存的就是在环内的点
for(int i = 1; i <= p; ++i)
for(int j = 0;j < G[loop_num[i]].size(); ++j){//枚举删掉环内的边
memset(vis,0,sizeof(vis));
q = 0;
vis[1] = 1;
ux = loop_num[i];uy = G[i][j];//需要删的边所连接的两个点
dfs1(1);
if(q==n) choseans();//如果q=n就寻找更优解
}
for(int i = 1; i <= n; ++i) printf("%d ",f[i]);
}
return 0;
}
这份代码我自认为写的没有什么太大问题但是样例都过不了,调了2天了,人都裂开了,有没有大佬能帮帮我!