http://poj.org/problem?id=2337
题意:按最字典序最小的顺序输出欧拉路。
这道题用的使用中回溯的方法,但是忘记掉叫什么名字了,暂时称其为欧拉路输出算法吧~
其核心代码为:
void find_eularpath(int u) {
int sz = g[u].size();
for(int i=0;i<sz;i++) {
int v = g[u][i].v;
if(!g[u][i].vis) {
g[u][i].vis = 1;
find_eularpath(v);
sta.push(g[u][i].name);
}
}
}
void print_path() {
string s = sta.top();
sta.pop(); cout << s;
while(!sta.empty()) {
s = sta.top(); sta.pop();
cout << "." << s;
}
cout << endl;
}
完整代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <stack>
using namespace std;
const int N = 26;
struct node {
int v; bool vis; string name;
node () { v = 0; vis = false; }
bool operator < (const node & b) const {
return name < b.name;
}
};
int T , n , f[N] , d[N] , key;
vector <node> g[N];
stack <string> sta;
bool flag[N];
void init() { for(int i=0;i<N;i++) f[i] = i; }
int find(int x) { return x == f[x] ? x : f[x] = find(f[x]); }
void Union(int x,int y) {
int a = find(x) , b = find(y); f[a]=f[b]=f[x]=f[y]=min(a,b);
}
bool check(int &key) {
int ans1 = 0 , ans2 = 0;
key = -1;
for(int i=0;i<N;i++) {
if(d[i] == 1) ans1 ++ , key = i;
else if(d[i] == -1) ans2 ++;
else if(d[i] != 0) return false;
}
int cnt = 0;
for(int i=0;i<N;i++) {
if(flag[i] && find(i) == i) cnt ++;
}
return cnt == 1;
}
void find_eularpath(int u) {
int sz = g[u].size();
for(int i=0;i<sz;i++) {
int v = g[u][i].v;
if(!g[u][i].vis) {
g[u][i].vis = 1;
find_eularpath(v);
sta.push(g[u][i].name);
}
}
}
void print_path() {
string s = sta.top();
sta.pop(); cout << s;
while(!sta.empty()) {
s = sta.top(); sta.pop();
cout << "." << s;
}
cout << endl;
}
void solve() {
scanf("%d",&n);
init();
memset(d,0,sizeof(d));
memset(flag,0,sizeof(flag));
while(!sta.empty()) sta.pop();
for(int i=0;i<N;i++) g[i].clear();
char ch[111];
for(int i=0;i<n;i++) {
scanf("%s" , ch);
int len = strlen(ch);
int u = ch[0] - 'a' , v = ch[len-1] - 'a';
Union(u , v);
flag[u] = flag[v] = true;
d[u] ++; d[v] --;
node edge;
edge.v = v; edge.vis = false;
edge.name = ch;
g[u].push_back(edge);
}
if(!check(key)) {
puts("***");
return;
}
for(int i=0;i<N;i++) {
sort(g[i].begin() , g[i].end());
}
if(key == -1) {
for(int i=0;i<N;i++)
if(flag[i]) {
find_eularpath(i);
break;
}
}
else find_eularpath(key);
print_path();
}
int main() {
scanf("%d" , &T);
while(T--) {
solve();
}
return 0;
}