分析:这个题的数据范围很小,直接打印全排列去判断也能过,但是这里存在两个剪枝,第一个,如果当前的距离已经大于前面距离的最小值,则剪枝,还有一个就是如果与当前结点相连的边数大于等于前面距离的最小值,则剪枝
1 #include "iostream" 2 #include "cstdio" 3 #include "cstring" 4 #include "string" 5 #include "map" 6 #include "set" 7 #include "vector" 8 #include "algorithm" 9 #include "cmath" 10 using namespace std; 11 const int INF=30; 12 const int maxn=30; 13 char a[maxn]; 14 char t[maxn]; 15 string s; 16 int minx; 17 map<char,string>mp; 18 void dfs(int cur,char B[],char vis[],vector<char> &c,int n){ 19 if(cur==n){ 20 int maxn=0; 21 int flag=0; 22 for(int i=0;i<n;i++){ 23 for(int j=0;j<(int)mp[B[i]].length();j++){ 24 int pos; 25 for(int k=0;k<n;k++){ 26 char ch=mp[B[i]][j]; 27 if(B[k]==mp[B[i]][j]){ 28 pos=k; break; 29 } 30 } 31 maxn=max(maxn,abs(pos-i)); 32 if(maxn>minx){ 33 flag=1; break; 34 } 35 } 36 if(flag) break; 37 } 38 if(maxn<minx&&!flag){ 39 minx=maxn; 40 c.clear(); 41 for(int i=0;i<n;i++) 42 c.push_back(B[i]); 43 } 44 }else{ 45 for(int i=0;i<n;i++){ 46 int ok=0; 47 for(int j=0;j<cur;j++) 48 if(vis[i]==B[j]){ 49 ok=1; break; 50 } 51 if(!ok){ 52 B[cur]=vis[i]; 53 dfs(cur+1,B,vis,c,n); 54 } 55 } 56 } 57 } 58 59 int main() 60 { 61 while(cin>>s) 62 { 63 if(s[0]=='#') break; 64 int len=s.length(); 65 int i=0; 66 set<char> str; 67 while(i<len){ 68 char ch; 69 while(i<len&&s[i]!=':'){ 70 ch=s[i]; 71 str.insert(ch); 72 i++; 73 } 74 i++; 75 while(i<len&&s[i]!=';'){ 76 mp[ch]+=s[i]; 77 str.insert(s[i]); 78 i++; 79 } 80 i++; 81 } 82 set<char>::iterator set_iter=str.begin(); 83 int k=0; 84 for(;set_iter!=str.end();set_iter++){ 85 a[k++]=*set_iter; 86 } 87 minx=INF; 88 vector<char> Q; 89 dfs(0,t,a,Q,k); 90 for(int i=0;i<Q.size();i++){ 91 printf("%c ",Q[i]); 92 } 93 printf("-> %d ",minx); 94 for(int i=0;i<k;i++) 95 mp[a[i]]=""; 96 } 97 }