Following Orders - POJ 1270 - Virtual Judge
https://vjudge.net/problem/POJ-1270
输入由一系列约束规范组成。每个约束规范都由两行组成:一行为变量列表,后面一行为行为约束列表。约束由一对变量给出,其中 x y 表示 x < y。所有变量都是单个小写字母。
对每个约束规范,都以字典顺序单行输出与约束一致的所有排序。不同约束规范输出以空行分隔。
a b f g
a b b f
v w x y z
v y x v z v w v
abfg
abgf
agbf
gabf
wxzvy
wzxvy
xwzvy
xzwvy
zwxvy
zxwvy
根据输入样例1,构建的图形结构如下图所示
本问题需要按照字典输出所有拓扑序列,因此使用回溯法搜索所有拓扑序列。注意,达到叶子时输出,回溯时需要还原现场。
1 将变量列表的字符转换为数字并统计出现次数,累计变量列表的长度。
2 将每对约束都转换为数字,用邻接矩阵存储并统计入度。
3 以回溯法求解所有拓扑序列并输出。
package graph.poj1270;
import java.util.Scanner;
public class Poj1270 {
static final int maxn = 50;
static int map[][]; // 邻接矩阵
static int in[]; // 入度
static int s[]; // 标记出现
static int ans[];
static int len; // 字符串长度
static int num; // 秩序长度
// 回溯法找所有的拓扑序列
static void dfs(int t) {
if (t >= len) {
for (int i = 0; i < len; i++)
System.out.print((char) (ans[i] + 'a'));
System.out.println();
}
for (int i = 0; i < 26; i++) {
if (in[i] == 0 && s[i] == 1) {
s[i]--;
for (int j = 0; j < 26; j++)
if (map[i][j] == 1)
in[j]--;
ans[t] = i;
dfs(t + 1);
for (int j = 0; j < 26; j++) // 回溯还原现场
if (map[i][j] == 1)
in[j]++;
s[i]++;
}
}
}
public static void main(String[] args) {
while (true) {
Scanner scanner = new Scanner(System.in);
String str = scanner.nextLine();
map = new int[maxn][maxn];
in = new int[maxn];
s = new int[maxn];
ans = new int[maxn];
len = str.length();
int i, j = 0;
for (i = 0; i < len; i++) {
if (str.charAt(i) != ' ') {
s[str.charAt(i) - 'a']++;
j++;
}
}
len = j;
String ord = scanner.nextLine();
num = ord.length();
for (i = 0; i < num; i += 2) {
int u = ord.charAt(i) - 'a';
i += 2;
int v = ord.charAt(i) - 'a';
map[u][v] = 1;
in[v]++;
}
dfs(0);
System.out.println();
}
}
}
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/chengqiuming/article/details/125836504
内容来源于网络,如有侵权,请联系作者删除!