按照USACO上面讲的哈密顿回路算法做的,不是完全懂。。。大致理解是那种方法对任一节点,会先处理完别的节点,然后才将这个节点加到路径里面。所以最后获得的是一个路径的倒序。如果你想要获得正确的序列(字典序,从小到大),那么你仍旧需要按照你想要的顺序来(即从较小的那个奇数度的点开始,然后每次处理的时候先处理邻接节点中最小的那个),最后倒序输出就好。
代码如下:
/*
ID: thestor1
LANG: C++
TASK: fence
*/
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cassert>
#include <string>
#include <algorithm>
#include <stack>
#include <set>
#include <queue>
using namespace std;
const int maxnum = 500;
int main()
{
FILE *fin = fopen ("fence.in", "r");
FILE *fout = fopen ("fence.out", "w");
//freopen("log_1.txt", "w", stdout);
int f;
fscanf(fin, "%d", &f);
vector<multiset<int> > vertexes;
vertexes.resize(maxnum);
fill(vertexes.begin(), vertexes.end(), multiset<int>());
int maxv = -1;
for(int i = 0; i < f; ++i)
{
int u, v;
fscanf(fin, "%d%d", &u, &v);
u--, v--;
vertexes[u].insert(v);
vertexes[v].insert(u);
maxv = max(u, v) > maxv ? max(u, v) : maxv;
}
int u = -1;
//for(int i = maxv; i >= 0; --i)
for(int i = 0; i <= maxv; ++i)
{
if(vertexes[i].size() % 2 == 1)
{
u = i;
break;
}
}
if(u == -1)
{
u = 0;
}
stack<int> st;
st.push(u);
stack<int> path;
while(!st.empty())
{
int u = st.top();
//st.pop();
if(vertexes[u].empty())
{
//fprintf(fout, "%d\n", u + 1);
path.push(u + 1);
st.pop();
}
else
{
int v = *vertexes[u].begin();
vertexes[u].erase(vertexes[u].begin());
vertexes[v].erase(vertexes[v].find(u));
st.push(v);
}
}
while(!path.empty())
{
fprintf(fout, "%d\n", path.top());
path.pop();
}
return 0;
}