给出一个图节点数为n(n8)让这些节点排序,使得节点的最大带宽要最小,最大带宽就是排列里面与节点相离最远的距离。
有两种方法,第一,因为n比较小就可以枚举全部,然后一个一个的比较,还有一种就是边排列边比较。只要其中两个节点的距离大于目前最大,那么下面的排列可以直接省去。
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 10;
int id[256], letter[maxn];
int P[maxn], bestP[maxn], pos[maxn]; vector<int>u, v; int ans;
void dfs(int n,int *A,int cur) {
if (cur == n) {
for (int i = 0; i < n; i++)pos[A[i]] = i;
int bandwidth = 0;
for (int i = 0; i < u.size(); i++) {
bandwidth = max(bandwidth,abs(pos[u[i]] - pos[v[i]]));
}
if (ans > bandwidth) {
ans = bandwidth;
for (int i = 0; i < n; i++)bestP[i] = A[i];
}
}
else for (int i = 0; i < n; i++) {
int ok = 1;
for (int j = 0; j < cur; j++) {
if (A[j] == i)ok = 0;
}
if (ok) {
A[cur] = i;
dfs(n,A,cur + 1);
}
}
}
int main() {
char input[1000];
while(scanf("%s", input) == 1 && input[0] != '#') {
int n = 0; memset(pos, 0, sizeof(pos));
memset(bestP, 0, sizeof(bestP));
u.clear(); v.clear();
for (char ch = 'A'; ch < 'Z'; ch++) {
if (strchr(input, ch) != NULL) {
id[ch] = n++;
letter[id[ch]] = ch;
}
}
int len = strlen(input), p = 0, q = 0;
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++;
}
ans = n; int A[10];
dfs(n, A, 0);
for (int i = 0; i < n; i++) printf("%c ", letter[bestP[i]]);
printf("-> %d\n", ans);
}
return 0;
}
下面这种是使用了next_permutation方法
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 10;
int id[256], letter[maxn];
int main() {
char input[1000];
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;
}
// 处理输入
int len = strlen(input), p = 0, q = 0;
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[maxn], bestP[maxn], pos[maxn], 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 bandwidth = 0;
for (int i = 0; i < u.size(); i++)
bandwidth = max(bandwidth, abs(pos[u[i]] - pos[v[i]])); // 计算带宽
if (bandwidth < ans) {
ans = bandwidth;
memcpy(bestP, P, sizeof(P));
}
} while (next_permutation(P, P + n));
// 输出
for (int i = 0; i < n; i++) printf("%c ", letter[bestP[i]]);
printf("-> %d\n", ans);
}
return 0;
}