Riding the Fences
2013-10-28 19:48
253 查看
题意:有F个栅栏,每个栅栏连接编号分别为x、y(均在[1, 500]内)的点,求最小欧拉回路。回路用编号序列代表,最小的定义:用500进制表示回路编号的序列是最小的。
解题思路:
典型的求欧拉回路的问题
用邻接表adj_table[i][j]来表示这张图。adj_table[i][0] = k表示点i有k个邻节点,那么adj_table[i][1...k]就代表了这k个邻节点的编号
参考(http://cerberus.delos.com:791/usacotext2?a=bhJRyLLAHTZ&S=euler)下面的求欧拉回路的过程,编写生成以节点location为起点的回路的函数FindCircuit(location)
FindCircuit(location),首先初始化一个栈stack和用来保存回路的数组circuit,并用两个变量stack_top和circuit_pos来维护两者
如果location没有邻节点,那么location就是新找到的回路节点,存到circuit中。然后将栈顶的元素取出作为新的location,如果栈空则执行完毕。如果location有邻节点,将location放到栈中,然后取出其最小的邻节点作为新的location,并将连接二者的边从邻接表中删去
循环执行5,直至栈空,那么就找到了以location为起点的欧拉回路
因为所给的输入都有欧拉回路。首先寻找第一个度是奇数的点为location,如果均为偶数,则度不为0的第一个点为location。然后执行FindCircuit(location)即可得到输出
代码:
解题思路:
典型的求欧拉回路的问题
用邻接表adj_table[i][j]来表示这张图。adj_table[i][0] = k表示点i有k个邻节点,那么adj_table[i][1...k]就代表了这k个邻节点的编号
参考(http://cerberus.delos.com:791/usacotext2?a=bhJRyLLAHTZ&S=euler)下面的求欧拉回路的过程,编写生成以节点location为起点的回路的函数FindCircuit(location)
FindCircuit(location),首先初始化一个栈stack和用来保存回路的数组circuit,并用两个变量stack_top和circuit_pos来维护两者
如果location没有邻节点,那么location就是新找到的回路节点,存到circuit中。然后将栈顶的元素取出作为新的location,如果栈空则执行完毕。如果location有邻节点,将location放到栈中,然后取出其最小的邻节点作为新的location,并将连接二者的边从邻接表中删去
循环执行5,直至栈空,那么就找到了以location为起点的欧拉回路
因为所给的输入都有欧拉回路。首先寻找第一个度是奇数的点为location,如果均为偶数,则度不为0的第一个点为location。然后执行FindCircuit(location)即可得到输出
代码:
/* ID: zc.rene1 LANG: C PROG: fence */ #include<stdio.h> #include<stdlib.h> #include<string.h> #define MAX_NODES 500 int F; int adj_table[MAX_NODES + 1][MAX_NODES + 1]; int FindLeast(int location) { int min = MAX_NODES + 1, min_i = -1; int len = adj_table[location][0]; int i = 1, j, count = 0; while (count < len) { if (adj_table[location][i] == -1) { i++; continue; } else { count++; if (adj_table[location][i] < min) { min = adj_table[location][i]; min_i = i; } i++; } } j = adj_table[location][min_i]; adj_table[location][min_i] = -1; adj_table[location][0]--; i = 1; while (adj_table[j][i] != location) { i++; } adj_table[j][0]--; adj_table[j][i] = -1; return min; } void FindCircuit(int location, FILE *fout) { int *stack = (int *)malloc((F + 1) * sizeof(int)); int *circuit = (int *)malloc((F + 1) * sizeof(int)); int circuit_pos = 0, stack_top = -1; memset(stack, 0, (F + 1) * sizeof(int)); memset(circuit, 0, (F + 1) * sizeof(int)); while (1) { if (adj_table[location][0] == 0) { circuit[circuit_pos++] = location; if (stack_top == -1) { break ; } else { location = stack[stack_top--]; } } else { stack[++stack_top] = location; location = FindLeast(location); } } int i; for (i=circuit_pos-1; i>=0; i--) { fprintf(fout, "%d\n", circuit[i]); } } int main(void) { FILE *fin, *fout; int i, j, k; fin = fopen("fence.in", "r"); fout = fopen("fence.out", "w"); /*get the input*/ memset(adj_table, 0, (MAX_NODES + 1) * (MAX_NODES + 1) * sizeof(int)); fscanf(fin, "%d", &F); for (i=0; i<F; i++) { fscanf(fin, "%d %d", &j, &k); adj_table[j][0]++; adj_table[j][adj_table[j][0]] = k; adj_table[k][0]++; adj_table[k][adj_table[k][0]] = j; } /*start to find Eulerian Tours*/ for (i=1; i<=MAX_NODES; i++) { if (adj_table[i][0] % 2 == 1) { FindCircuit(i, fout); break; } } if (i > MAX_NODES) { for (i=1; i<=MAX_NODES; i++) { if (adj_table[i][0] != 0) { FindCircuit(i, fout); break; } } } return 0; }
相关文章推荐
- 欧拉路径, 欧拉回路 USACO Riding the Fences
- 欧拉回路 USACO 3.3.1 Riding the Fences
- USACO Riding the fences and C implement
- 洛谷 P2731 骑马修栅栏 Riding the Fences
- usaco Riding the Fences
- usaco 3.2 Riding The Fences
- 洛谷 P2731 骑马修栅栏 Riding the Fences
- USACO3.3.1--Riding the Fences
- 洛谷 P2731 骑马修栅栏 Riding the Fences
- usaco Riding the Fences(欧拉回路模板)
- USACO-Section 3.3-PROB Riding The Fences
- 【题解】Luogu 骑马修栅栏 Riding the Fences (欧拉回路+搜索)
- usaco 3.3 Riding the Fences
- USACO / Riding the Fences (欧拉路径)
- USACO Section 3.3: Riding the Fences
- Riding the Fences
- [USACO3.3.1]Riding the Fences
- USACO - Riding the Fences (Fleury算法找欧拉路径/欧拉回路模板)
- usaco Riding the Fences
- USACO: Chap3 Riding the Fences