题解:建立这个图的反图,然后进行哈密顿回路
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
using namespace std;
typedef long long LL;
const int maxN = 400;
inline void reverse(int arv[maxN + 7], int s, int t){
int temp;
while(s < t){
temp = arv[s];
arv[s] = arv[t];
arv[t] = temp;
s++;
t--;
}
}
void Hamilton(int ans[maxN + 7], bool map[maxN + 7][maxN + 7], int n){
int s = 1, t;
int ansi = 2;
int i, j;
int w;
int temp;
bool visit[maxN + 7] = {false};
for(i = 1; i <= n; i++) if(map[s][i]) break;
t = i;
visit[s] = visit[t] = true;
ans[0] = s;
ans[1] = t;
while(true){
while(true){
for(i = 1; i <= n; i++){
if(map[t][i] && !visit[i]){
ans[ansi++] = i;
visit[i] = true;
t = i;
break;
}
}
if(i > n) break;
}
w = ansi - 1;
i = 0;
reverse(ans, i, w);
temp = s;
s = t;
t = temp;
while(true){
for(i = 1; i <= n; i++){
if(map[t][i] && !visit[i]){
ans[ansi++] = i;
visit[i] = true;
t = i;
break;
}
}
if(i > n) break;
}
if(!map[s][t]){
for(i = 1; i < ansi - 2; i++)
if(map[ans[i]][t] && map[s][ans[i + 1]])break;
w = ansi - 1;
i++;
t = ans[i];
reverse(ans, i, w);
}
if(ansi == n) return;
for(j = 1; j <= n; j++){
if(visit[j]) continue;
for(i = 1; i < ansi - 2; i++)if(map[ans[i]][j])break;
if(map[ans[i]][j]) break;
}
s = ans[i - 1];
t = j;
reverse(ans, 0, i - 1);
reverse(ans, i, ansi - 1);
ans[ansi++] = j;
visit[j] = true;
}
}
int main(){
int N, M;
while(~scanf("%d%d", &N, &M) && (N || M)){
N *= 2;
bool map[maxN + 7][maxN + 7] = {0};
int ans[maxN + 7] = {0};
int ansi = 0;
for(int i = 0; i <= N; i++)
for(int j = 0; j <= N; j++)
i == j ? map[i][j] = map[j][i] = 0 : map[i][j] = map[j][i] = 1;
memset(ans, 0, sizeof(ans));
for(int i = 1; i <= M; i++){
int u, v;
scanf("%d%d", &u, &v);
map[u][v] = map[v][u]= 0;
}
Hamilton(ans, map, N);
for(int i = 0; i < N; i++)
printf(i == 0 ? "%d":" %d", ans[i]);
printf("\n");
}
return 0;
}