我自认为这题我做的比较精妙的地方在于求带宽的函数,我没有采用逐个比较的一般思路,而是根据位置进行直接判定最大带宽。一般思路要选定每个节点,然后将与该节点相连的节点记录下来,在排列中依次确定其距该节点的位置,取最大值作为该节点的带宽,而一个排列的带宽则是所有节点带宽的最大值,复杂度为O(n^n)。我做的复杂度要低得多,直接判断第一个位置和最后一个位置的节点在图中是否是相连的,如果是那么该排列的带宽一定是最大值(节点数-1),不是再判断距离为节点数-2的节点对(此时有两对)......如此判断复杂度只要O(n)不到
转载请注明出处,谢谢!
http://blog.csdn.net/monkeyduck
#include<iostream> #include<cstring> using namespace std; char input[100]; int nodenum,Min,result[10],order[10],node[10],path[30][30]; bool vis[10],letter[30]; int getBandwidth() { int i; for (int d=nodenum-1;d>0;d--) for (i=0;i+d<nodenum;i++) if (path[order[i]][order[i+d]]==1) return d; } void dfs(int cur) { int i; if (cur==nodenum) { int bandwidth=getBandwidth(); if (bandwidth<Min) { Min=bandwidth; memcpy(result,order,sizeof(order)); } } else { for (i=0;i<nodenum;i++) { if (!vis[i]) { order[cur]=node[i]; vis[i]=1; dfs(cur+1); vis[i]=0; } } } } void init() { nodenum=0; vis[10],letter[30]; memset(vis,0,sizeof(vis)); memset(result,0,sizeof(result)); memset(node,0,sizeof(node)); memset(order,0,sizeof(order)); Min=8; } int main() { while (cin>>input&&input[0]!='#') { int len=strlen(input); int dex=0; memset(letter,0,sizeof(letter)); memset(path,0,sizeof(path)); while (dex<=len) { int start=input[dex]-'A'; letter[start]=1; dex=dex+2; char ch=input[dex++]; while (ch!=';'&&ch!='\0') { int end=ch-'A'; letter[end]=1; path[start][end]=path[end][start]=1; ch=input[dex++]; } } init(); for (int i=0;i<27;i++) { if(letter[i]) node[nodenum++]=i; } dfs(0); for (int i=0;i<nodenum;i++) { cout<<char('A'+result[i])<<' '; } cout<<"-> "<<Min<<endl; } return 0; }