注意要先为出现的节点进行编号。而且还要按字典序而非出现顺序。
dfs枚举排列。
dfs枚举排列。
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <algorithm>
#include <sstream>
#include <utility>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <cctype>
#define CLEAR(a, b) memset(a, b, sizeof(a))
#define IN() freopen("in.txt", "r", stdin)
#define OUT() freopen("out.txt", "w", stdout)
#define LL long long
#define maxn 1005
#define maxm 10005
#define mod 1000000007
#define INF 1000000007
#define eps 1e-5
#define PI 3.1415926535898
#define N 26
using namespace std;
//-------------------------CHC------------------------------//
map<char, int> id;
map<int, char> letter;
char in[maxn];
int G[26][26];
int a[10];
int ans[10];
bool vis[10];
int n;
int minband;
void init() {
n = 0;
id.clear();
letter.clear();
CLEAR(G, 0);
CLEAR(vis, 0);
minband = INF;
}
void build() {
for (char i = 'A'; i <= 'Z'; ++i) {
if (strchr(in, i) != NULL)
id[i] = n, letter[n++] = i;
}
int i = 0;
while (in[i]) {
int u = id[in[i]];
i += 2;
while (in[i] && in[i] != ';') {
int v = id[in[i++]];
G[u][v] = 1;
}
if (in[i]) ++i;
}
}
int Bandwidth(int cur) {
int maxdis = 0;
for (int i = 0; i < cur; ++i) {
for (int j = 0; j < cur; ++j) {
if (G[a[i]][a[j]]) {
int dis = abs(i - j);
maxdis = max(maxdis, dis);
}
}
}
return maxdis;
}
void dfs(int cur) {
if (cur == n) {
int band = Bandwidth(n);
if (band < minband) {
minband = band;
memcpy(ans, a, sizeof(a));
}
return;
}
if (Bandwidth(cur) >= minband) return; //普通剪枝
for (int i = 0; i < n; ++i) {
if (!vis[i]) {
a[cur] = i;
vis[i] = 1;
int cnt = 0;
for (int j = 0; j < n; ++j) //最优性剪枝
if (!vis[j] && G[i][j]) cnt++;
if (cnt >= minband) return;
dfs(cur + 1);
vis[i] = 0;
}
}
}
int main() {
while (scanf("%s", in) && in[0] != '#') {
init();
build();
dfs(0);
for (int i = 0; i < n; ++i)
printf("%c ", letter[ans[i]]);
printf("-> %d\n", minband);
}
return 0;
}
STL实现
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <algorithm>
#include <sstream>
#include <utility>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <cctype>
#define CLEAR(a, b) memset(a, b, sizeof(a))
#define IN() freopen("in.txt", "r", stdin)
#define OUT() freopen("out.txt", "w", stdout)
#define LL long long
#define maxn 1005
#define maxm 10005
#define mod 1000000007
#define INF 1000000007
#define eps 1e-5
#define PI 3.1415926535898
#define N 26
using namespace std;
//-------------------------CHC------------------------------//
typedef pair<int, int> pii;
vector<pii> rela;
map<char, int> id;
map<int, char> letter;
char in[maxn];
int a[10], ans[10];
int n;
void init() {
n = 0;
rela.clear();
id.clear();
letter.clear();
}
void build() {
for (char i = 'A'; i <= 'Z'; ++i) {
if (strchr(in, i) != NULL)
id[i] = n, letter[n++] = i;
}
int i = 0;
while (in[i]) {
int u = id[in[i]];
i += 2;
while (in[i] && in[i] != ';') {
int v = id[in[i++]];
rela.push_back(pii(u, v));
}
if (in[i]) ++i;
}
}
int main() {
while (scanf("%s", in) && in[0] != '#') {
init();
build();
for (int i = 0; i < n; ++i) a[i] = i;
int pos[10];
int minband = INF;
do {
for (int i = 0; i < n; ++i) pos[a[i]] = i;
int bandwidth = 0;
for (int i = 0; i < rela.size(); ++i)
bandwidth = max(bandwidth, abs(pos[rela[i].first] - pos[rela[i].second]));
if (bandwidth < minband) {
minband = bandwidth;
memcpy(ans, a, sizeof(a));
}
} while (next_permutation(a, a + n));
for (int i = 0; i < n; ++i)
printf("%c ", letter[ans[i]]);
printf("-> %d\n", minband);
}
return 0;
}