这是一道暴力都能过的题,重点其实在于理解题意,输入过程也有一点繁琐。
1.题意
先给定一个无向图,要重新安排结点的顺序,使得相邻的节点在排列中的最大距离最小
2.Solution
明显的爆搜,难就难在如何建模,其实只要把出现过的字符放到一个数组记录起来,然后搜索的时候依次安排每个节点的字母
分块讲解:
(1)输入
//首先我们可以先把":"前面的字符提出来作为u,再在:后面的字符拿出来做v //Coder-cjh void init(){ mind=1e9;tot=0; memset(v,0,sizeof(v)); memset(id,0,sizeof(id)); memset(can,0,sizeof(can));//多测不清空,爆零两行泪 for(int i=0;i<s.size();i++) if(isalpha(s[i])) if(!id[s[i]-'A'])id[s[i]-'A']=1,tr[++tot]=s[i]-'A';//如果出现了没有遇到的就记录 int ls=s[0]-'A';//第一个字符一定会是字母 for(int i=1;i<s.size();i++) if(s[i]==':'){//如果是“:”,之后的就是v ++i; while(i<s.size()&&s[i]!=';')v[ls][s[i]-'A']=v[s[i]-'A'][ls]=1,++i;//一直读到; } else if(s[i]!=';')ls=s[i]-'A';//再找到下一次的u }
(2)搜索
//Coder-cjh bool cmp(int a[],int ans[]){//因为有点怂,所以手写cmp函数 for(int i=1;i<=tot;i++) if(a[i]!=ans[i]) return a[i]>ans[i]; return false; } void dfs(int step,int md){ if(md>mind)return;//最优性剪枝 if(step==tot+1){ if(md==mind&&cmp(a,ans))return; mind=md,memcpy(ans,a,sizeof(a)); return; } for(int i=1;i<=tot;i++) if(!can[tr[i]]){ can[tr[i]]=1;//打上标记 a[step]=tr[i]; int tmp=0; for(int j=1;j<step;j++) if(v[tr[i]][a[j]])tmp=max(tmp,step-j);//计算出目前的带宽 dfs(step+1,max(tmp,md)); can[tr[i]]=0; } }