poj1041 无向图欧拉回路 按最小升序输出
2010-08-24 21:27
246 查看
John's trip
这道题很不错,由于图已经保证连通,首先用度数是否是偶数,判断图是否是欧拉图,然后,输出最小升序,就成了一大难题,百科上有代码,这题让我理解了深搜的又一强大功能,其实就是每次都从小往大的搜,先搜得一个最小序环,然后对环上的每一点进行搜索,其实对于欧拉图而言,每个点要么就只剩一个点,什么也搜不到了,要么还有一个环,只要把环上路径全都插入到对应位置上,用栈存路径,每次只有回溯到当前点,就是说当前点的后继都已经搜过了的时候,才把当前点入栈,这样一来倒着输出,就能得到一个欧拉回路,而且是最小升序。
就是这样一个代码,就能实现欧拉回路的输出,唯一一点特别的就是,stk[++top] = e,是在v点搜完了才执行的,想想就知道这有什么含义,这样才是真正的最小序欧拉回路。实现代码见下:
代码
这道题很不错,由于图已经保证连通,首先用度数是否是偶数,判断图是否是欧拉图,然后,输出最小升序,就成了一大难题,百科上有代码,这题让我理解了深搜的又一强大功能,其实就是每次都从小往大的搜,先搜得一个最小序环,然后对环上的每一点进行搜索,其实对于欧拉图而言,每个点要么就只剩一个点,什么也搜不到了,要么还有一个环,只要把环上路径全都插入到对应位置上,用栈存路径,每次只有回溯到当前点,就是说当前点的后继都已经搜过了的时候,才把当前点入栈,这样一来倒着输出,就能得到一个欧拉回路,而且是最小升序。
void dfs(int u){ int i, v, e; for (i = 1; i <= num[u]; i++){ e = adj[u][i]; if (!mark[e]){ v = map[u][e]; mark[e] = 1; dfs(v); stk[++top] = e; } } }
就是这样一个代码,就能实现欧拉回路的输出,唯一一点特别的就是,stk[++top] = e,是在v点搜完了才执行的,想想就知道这有什么含义,这样才是真正的最小序欧拉回路。实现代码见下:
代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define NN 46
#define MM 1998
int map[NN][MM];// map[u][e] = v,表示点u通过边e连接到v
int adj[NN][MM]; // adj[u][i] = e,表示u的第i条临边是e
int num[NN]; // 记录每个点的临边条数
int mark[MM];
int stk[MM]; // 记录欧拉路径
int idx, S, top;
int Min(int x, int y){
return x < y ? x : y;
}
int cmp(const void *a, const void *b){
return *(int *)a - *(int *)b;
}
void dfs(int u){ int i, v, e; for (i = 1; i <= num[u]; i++){ e = adj[u][i]; if (!mark[e]){ v = map[u][e]; mark[e] = 1; dfs(v); stk[++top] = e; } } }
int main()
{
int x, y, z, i, maxN;
while(scanf("%d%d", &x, &y) != EOF){
if (x == 0 && y == 0) break;
memset(num, 0, sizeof(num));
scanf("%d", &z);
S = Min(x, y);
adj[x][++num[x]] = z;
adj[y][++num[y]] = z;
map[x][z] = y;
map[y][z] = x;
while(scanf("%d%d", &x, &y) != EOF){
if (x == 0 && y == 0) break;
scanf("%d", &z);
adj[x][++num[x]] = z;
adj[y][++num[y]] = z;
map[x][z] = y;
map[y][z] = x;
}
for (i = 1;; i++){
if(num[i] == 0) break;
if (num[i] & 1) break;
}
if (num[i] != 0){
puts("Round trip does not exist.");
continue;
}
maxN = i - 1;
for (i = 1; i <= maxN; i++){ // 对点i的临边排序
qsort(adj[i] + 1, num[i], sizeof(int), cmp);
}
memset(mark, 0, sizeof(mark));
top = 0;
dfs(S);
for (i = top; i > 1; i--){
printf("%d ", stk[i]);
}
printf("%d\n", stk[i]);
}
return 0;
}
相关文章推荐
- (POJ 1041)John's trip [无向欧拉图] 输出字典序最小的欧拉回路
- poj 1041(欧拉回路+输出字典序最小路径)
- poj 1041(欧拉回路+输出字典序最小路径)
- POJ 1041 John's trip 无向图的【欧拉回路】路径输出
- POJ 1041 John's trip(欧拉回路+输出路径)
- POJ 1041 - John's trip 输出欧拉回路路径边..通用做法
- 欧拉回路输出路径 POJ - 1041
- POJ 1041 John's trip 欧拉回路(输出路径)
- poj 2337 欧拉回路按照最小字典序输出+注意为了按最小字典序怎么处理邻接表
- poj1041 John's trip(欧拉回路+输出路径)
- poj 2337 欧拉回路输出最小字典序路径 ***
- (算法设计7.3.1.1)POJ 1041 John's trip(计算无向图的欧拉回路窃案字典序最小进行输出)
- poj 1041(字典序输出欧拉回路)
- poj1041 欧拉回路(值得好好看一下)
- hdu 1041 John's trip 输出欧拉回路
- POJ 1041 John's trip(欧拉回路)
- POJ 2230 Watchcow(欧拉回路:输出点轨迹)
- POJ 1041 John's trip (欧拉回路)
- poj 1041 John's trip(欧拉回路入门题)
- 【POJ - 3270 】Cow Sorting 【置换群 序列变升序最小花费】