直接回溯,比较麻烦的是数据的读取。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAX_SIZE 30 + 10
char Grap[MAX_SIZE];
int G[MAX_SIZE][MAX_SIZE];/*表示2个点相连*/
int n;
int A[MAX_SIZE];
int visa[MAX_SIZE];
int counts[MAX_SIZE];/*计算几点是否被访问过*/
int OK_Mat[MAX_SIZE];/*成功的数组*/
int MIN;
void dfs(int u,int cur)
{
/*判断每各个点之间联系*/
int mins=0;
for(int i=0;i<cur;i++)
for(int j=1;i+j<cur;j++)
{
int x=A[i],y=A[i+j];
if(G[x][y]) /*如果2个点相连*/
mins=mins>j?mins:j;/*是最大的一个宽带*/
if(mins>MIN) return ;
}
if(cur==n&&mins<MIN){
MIN=mins;
memcpy(OK_Mat,A,sizeof(OK_Mat));
return ;
}
for(int i=0;i<MAX_SIZE;i++)
if(counts[i]&&!visa[i]){
A[cur]=i;
visa[i]=1;
dfs(i,cur+1);
visa[i]=0;
}
}
int main(){
while(true){
scanf("%s",Grap);
n=0;/*计算节点的个数*/
MIN=99999;
memset(counts,0,sizeof(counts));
memset(G,0,sizeof(G));
memset(OK_Mat,0,sizeof(OK_Mat));
if(strcmp(Grap,"#")==0)
break;
char temp=Grap[0];
int L=strlen(Grap);
for(int i=0;i<L;i++)
if(isalpha(Grap[i])&&!counts[Grap[i]-'A']){
counts[Grap[i]-'A']++;
n++;
}
/*记录出现的点*/
for(int i=1;i<L;i++){/*记录点的连接状态*/
if(Grap[i]==':'){
for(i=i+1;i<L;i++){
if(Grap[i]==';'){
temp=Grap[i+1];
break;
}
G[temp-'A'][Grap[i]-'A']=1;/*计算有几个节点*/
G[Grap[i]-'A'][temp-'A']=1;/*计算有几个节点*/
}
}
}
for(int i=0;i<MAX_SIZE;i++){
memset(visa,0,sizeof(visa));
if(counts[i])/*如果是出现过的节点*/{
A[0]=i;
visa[i]=1;
dfs(i,1);
}
}
for(int i=0;i<n;i++)
printf("%c ",OK_Mat[i]+'A');
printf("-> %d",MIN);
printf("\n");
}
return 0;
}
本文深入探讨了图遍历算法中的回溯法实现,并通过具体的代码示例详细讲解了如何解决特定问题。从数据结构搭建到算法的具体实现,文章提供了一个完整的解决方案。
1744

被折叠的 条评论
为什么被折叠?



