题意是让我们找出在给出的结点中相邻结点的最大距离。
一开始我想用回溯法构造排列,然后存在一个数组里,之后再算。。可是这样二维数组要开到40000多了,不太可能实现。
参考了GooMaple的解题报告。非常好的思路,又可以让我回味一个晚上了╮(╯▽╰)╭
#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std;
int G[30][30];
int alpha[30], node[10], ans[10];
void GetSequ(int cur);
int main()
{
//freopen("input.txt", "r", stdin);
int i, j;
char str[100], ch;
int cnt, minAllMax, maxLen;
while (fgets(str, 100, stdin))
{
if (str[0] == '#')
break;
memset(G, 0, sizeof(G));
memset(alpha, 0, sizeof(alpha));
cnt = 0;
minAllMax = (1 << 30) - 1;
int len = strlen(str);
//下面两个循环是为了统计出结点个数和结点所代表的编号,一个字母对应一个编号
for (i = 0; i < len; i++)
if (isalpha(str[i]))
alpha[str[i] - 'A'] = 1;
for (i = 0; i < 26; i++)
if (alpha[i])
node[cnt++] = i;
i = 0;
//下面是读取字符串部分,大家可以自由发挥。。
while (true)
{
while (str[i] != ':')
i++;
ch = str[i - 1];
i++;
while (str[i] != ';' && str[i] != '\n')
{
G[ch - 'A'][str[i] - 'A'] = G[str[i] - 'A'][ch - 'A'] = 1;
i++;
}
if (str[i] == '\n')
break;
}
do
{
maxLen = -1;
for (int i = 0; i < cnt; i++)
for (j = i + 1; j < cnt; j++)
{
if (G[node[i]][node[j]] && j - i > maxLen)
maxLen = j - i;
if (maxLen > minAllMax) //剪枝
break;
}
if (maxLen < minAllMax)
{
minAllMax = maxLen;
memcpy(ans, node, sizeof(node));
}
} while (next_permutation(node, node + cnt));
for (i = 0; i < cnt; i++)
printf("%c ", ans[i] + 'A');
printf("-> %d\n", minAllMax);
}
return 0;
}