acm.sgu.ru/problem.php?contest=0&problem=122
/*
*NAME:The Book
*LANG:C++
*SOURCE:sgu122
*METHOD:满足ORE条件的哈密顿回路构造.
*1、从起点,按照每次取与其相连且度数最小的点,形成一条长度为n链
*2、然后找到两个相邻的点i-1和i,满足1与i相连且i-1与n相连,这样删除之前i-1到i点边,就形成曼哈顿回路。
*/
#include <vector>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <sstream>
using namespace std;
const int MAXN = 1010;
const int INF = 0x3f3f3f3f;
int degree[MAXN], vis[MAXN];
int ans[MAXN], n;
vector<int> vt[MAXN];
void del(int x){
vis[x] = 1;
for(int i = 0; i < vt[x].size(); i++)
degree[vt[x][i]]--;
}
int find(int x){
int ret = -1;
for(int i = 0; i < vt[x].size(); i++){
int v = vt[x][i];
if(vis[v]) continue;
if(ret == -1) ret = v;
else if(degree[ret] > degree[v]) ret = v;
}
return ret;
}
bool check(int u, int v){
for(int i = 0; i < vt[u].size(); i++)
if(vt[u][i] == v) return true;
return false;
}
char s[4010];
int main(){
scanf("%d",&n); getchar();
for(int i=1; i<=n; i++){
int k = 0;
gets(s);
for (int j=0; s[j]; ++j){
if (s[j] != ' ') k = k*10 + s[j]-'0';
else {
vt[i].push_back(k);
degree[i]++;
k=0;
}
}
if (k!=0){
vt[i].push_back(k);
degree[i] ++;
k=0;
}
}
int pre = 1,ans[1] = pre;
for(int i = 2; i <= n; i++){
del(pre);
pre = find(pre);
ans[i] = pre;
}
for(int i = 2; i <= n; i++){//破链成环
if(check(1, ans[i]) == false) continue;
if(check(ans[n], ans[i - 1])){
printf("1");
for(int j = i; j <= n; j++)
printf(" %d", ans[j]);
for(int j = i - 1; j >= 2; j--)
printf(" %d", ans[j]);
printf(" 1\n");
break;
}
}
}