暴力枚举
刘汝佳书中说了半天如何剪枝,但是他的代码仓库中依旧是暴力枚举
代码参考刘汝佳的代码仓库
#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#pragma warning(disable:4996)
using namespace std;
int main()
{
char input[1000], letter[10];
int id[200];
while (scanf("%s", input)==1 && input[0] != '#')
{
int n = 0;
for (char ch = 'A'; ch <= 'Z'; ch++)
if (strchr(input, ch) != NULL) {
id[ch] = n++;
letter[id[ch]] = ch; //建立一个双映射,通过id数组可以找到节点字母对应编号
//通过letter数组可以找到编号对应字母
//这样做的目的是为了方便输出以及枚举全排列
}
//处理输入
int p = 0, q = 0, len = strlen(input);
vector<int> u, v; //存储无向边
for (;;)
{
while (p < len&&input[p] != ':') p++;
if (p == len) break;
while (q < len&&input[q] != ';') q++;
for (int i = p + 1; i < q; i++) {
u.push_back(id[input[p - 1]]);
v.push_back(id[input[i]]);
}
p++; q++;
}
int P[10], best_P[10], pos[10], ans = n;
for (int i = 0; i < n; i++) P[i] = i;
do {
for (int i = 0; i < n; i++) pos[P[i]] = i;
int best = 0;
for (int i = 0; i < u.size(); i++) {
best = max(best, abs(pos[u[i]] - pos[v[i]]));
if (best >= ans) break;
}
if (best < ans) {
ans = best;
memcpy(best_P, P, sizeof(P));
}
} while (next_permutation(P, P + n));
for (int i = 0; i < n; i++) printf("%c ", letter[best_P[i]]);
printf("-> %d\n", ans);
}
}