第一次写回溯。。发生了很多错误(虽然回溯应该是很简单的算法了,就是剪剪枝而已)
可能也有思考不全的因素,一开始老是想多减点枝,结果减多了。。虽然第一次的时间确实很可观。~
有一点可能很uva上题目的描述不一样,uva上说a single upper case character in the the range `A' to `Z'), followed by a `:'
节点只有一个的意思,但是貌似不是这样。。回去要搜搜其他大神的代码,多优化一下了。
#include<bits/stdc++.h>
using namespace std;
const int maxn=100;char s[maxn];
int kase=0,a[50],most[50],small,vis[maxn],A[50];
vector<int> G[20];
map<int,int> p;
void dfs(int cur) {
if(cur==kase) {
int h=-1;
for(int i=0;i<kase;i++)
for(int j=0;j<G[most[i]].size();j++){
int v=G[most[i]][j],k;
for( k=0;k<kase;k++)
if(most[k]==v) break;
if(abs(i-k)>h) h=abs(i-k);
}
small=h;
for(int j=0;j<kase;j++) A[j]=most[j];return ;
}
for(int i=0;i<kase;i++){
if(!vis[a[i]]){
int ok=1;
most[cur]=a[i]; vis[a[i]]=1;
for(int m=0;m<=cur;m++){
for(int j=0;j<G[most[m]].size();j++){
int v=G[most[m]][j],k;
if(vis[v]){ for(k=0;k<cur;k++)
if(most[k]==v) break;
if(abs(m-k)>=small) { ok=0;break; }
}
}
if(!ok) break;
}
if(ok)
dfs(cur+1);
vis[a[i]]=0;
}
}
}
int main() {
while(scanf("%s",s)!=EOF) {
if(s[0]=='#') return 0;
kase=0;
int n=strlen(s);
int star=0,maohao;
for(int i=0;i<n;i++){
if(isupper(s[i])&&!p.count(s[i]-'A')) { p[s[i]-'A']=1; a[kase++]=s[i]-'A'; }
if(s[i]==';'||i==n-1) {
if(i==n-1) i++;
for(int j=star;j<i;j++) if(s[j]==':') { maohao=j; break; }
for(int j=star;j<maohao;j++)
for(int k=maohao+1;k<i;k++) {
G[s[j]-'A'].push_back(s[k]-'A');
G[s[k]-'A'].push_back(s[j]-'A');
}
star=i+1;
}
}
sort(a,a+kase);small=100000;
memset(vis,0,sizeof(vis));
dfs(0) ;
for(int i=0;i<kase;i++)
printf("%c ",A[i]+'A');printf("-> %d\n",small);
for(int i=0;i<30;i++) G[i].clear();
p.clear();
}
return 0;
}