题目解析:从0结点开始,深搜找最短路,深搜也即枚举全排列,关键是在递归(保存所有的状态)中的每一层如果所有的顶点个数等于总顶点个数时,更新此时的最小值。
代码如下:
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int map[34][34];
int vis[34];
int num,ans,n;
void dfs(int cur,int step,int dist) //cur是当前点的标号,step是个数,dist是距离
{
if(step==num)
ans=min(ans,dist);
for(int i=1;i<n;i++)
{
if(vis[i])
{
vis[i]=0;
dfs(i,step+1,dist+map[cur][i]); //深搜的过程是1,返回上一层,2,取消标记,3,再找有无兄弟节点(邻接点)
vis[i]=1;
}
}
}
int main()
{
while(scanf("%d",&n)!=EOF&&n)
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
scanf("%d",&map[i][j]);
memset(vis,0,sizeof(vis)); // 用来标记即将被访问的点
int k;
scanf("%d",&k);
num=0; //用来统计被访问过的点的个数
for(int i=0;i<k;i++)
{
int j;
scanf("%d",&j);
if(!vis[j]) //如果一个顶点多次出现时只统计一次
{
vis[j]=1;
num++;
}
}
ans=999999999;
dfs(0,0,0);
printf("%d\n",ans);
}
return 0;
}