题目意思:给定n个节点,(n<=8),节点的编号为A~Z 来表示,要求找到一个节点的序列,使得该序列最大的节点的Bandwidth为所有序列中的最小值,(节点的Bandwidth是指和它所连接的点中和它距离最大的值)。
解题思路:由于最多只有8个节点,那么可以枚举这个解空间的所有情况,然后找到其中的最有解并且记录下它的节点顺序,那么我们可以通过求全排列的方法去一一枚举这些排列
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;
char s[100];
int G[30][30];
int a[10];
int ans[10];
int max_t,min_,dis_;
int main()
{
while(gets(s)!=NULL)
{
if(strcmp("#",s)==0)
break;
memset(G,0,sizeof(G));
int b=strlen(s);
int t=0;
for(int i=0; i<b; i++)
{
if(s[i]==':')
{
int a1=s[i-1]-'A';
int flag=1;
for(int k=0; k<t; k++)
{
if(a1==a[k])
{
flag=0;
break;
}
}
if(flag)
a[t++]=a1;
for(int j=i+1; j<b; j++)
{
if(s[j]==';')
break;
int a2=s[j]-'A';
G[a1][a2]=1;
flag=1;
for(int k=0; k<t; k++)
{
if(a2==a[k])
{
flag=0;
break;
}
}
if(flag)
a[t++]=a2;
}
}
}
/*printf("%d\n",t);
for(int i=0; i<30; i++)
{
for(int j=0; j<30; j++)
{
if(G[i][j])
printf("%c %c\n",i+'A',j+'A');
}
}
for(int i=0; i<t; i++)
printf("%c ",a[i]+'A');
printf("\n");*/
sort(a,a+t);
min_=10;
do
{
max_t=0;
for(int i=0; i<t; i++)
{
for(int j=0; j<t; j++)
{
if(G[a[i]][a[j]])
{
dis_=abs(j-i);
if(dis_>max_t)
max_t=dis_;
}
}
}
if(max_t<min_)
{
min_=max_t;
memcpy(ans,a,sizeof(a));
}
}
while(next_permutation(a,a+t));
for(int i=0;i<t;i++)
{
if(i)
printf(" ");
printf("%c",ans[i]+'A');
}
printf(" -> %d\n",min_);
}
return 0;
}