资源限制
内存限制:256.0MB C/C++时间限制:1.0s Java时间限制:3.0s Python时间限制:5.0s
问题描述
逗志芃是有妹子的现充,但是有时候妹子就是烦恼。因为逗志芃太逗了,所以这段时间妹子对逗志芃发动了技能无理取闹,妹子要去玩很多的景点。由于逗志芃之前抽机花费了太多的时间,不久以后又要微积分考试了,所以现在被妹子搞成暴走状态了。但是妹子永远是上帝,所以逗志芃只能带妹子出去玩,不过为了节约时间,他希望找到一条花费时间最少的一次性游览线路。
输入格式
第一行1个数n,表示逗志芃所在的城市有多少个景点,接下来是一个n*n的矩阵。a(i,j)表示i号景点到j号景点的路上花费的时间是多少。
接下来是一个数m,表示逗志芃妹子要去去的景点数目。由于妹子在无理取闹,所以可能会有重复的景点,不过只要去一次就可以了。接下来是m个数,就是妹子要去的景点编号。
输出格式
一个数,最少的花费时间。
样例输入
3
0 1 2
1 0 3
2 3 0
3
2 3 1
样例输出
3
数据规模和约定
0<n<=30,0<m<=20,时间<=1000000
解答:
利用佛洛依德算法先求最短路径,接着用dfs进行图的遍历操作;
#include<iostream>
using namespace std;
const int N=32;
int dp[N][N],n,visit[N],des[N],m,num;//其中visit是在dfs中进行访问的数组,des是在main中访问节点的矩阵
int result=1e6;
void floyd(int (*a)[N],int n){
for(int i = 1;i<=n;i++){
for(int j = 1;j<=n;j++){
for(int k =1;k<=n;k++){
if(a[i][j]>a[i][k]+a[k][j])
a[i][j]=a[i][k]+a[k][j];
}
}
}
}
void dfs(int cur, int cnt, int t) {
if(cnt == num) {
result = min(result, t);
return;
}
for(int i=1; i<=n; i++) {
if(des[i] && !visit[i] && dp[cur][i]+t <= result) {
visit[i] = 1;
dfs(i, cnt+1, t+dp[cur][i]);
visit[i] = 0;
}
}
}
int main(){
int a;
cin >> n;
for(int i = 1;i<=n;i++){
for(int j = 1;j<=n;j++){
cin >> dp[i][j];
}
}
floyd(dp,n);
cin >> m;
for(int i = 1;i<=m;i++){
cin >> a;
if(!des[a]){
des[a]=1;
num++;
}
}
for(int i =1;i<=n;i++){
if(des[i]){
for(int j =1;j<=n;j++)//这一步的操作是要把全部点置为0,因为原来我们从一个点开始遍历但是dfs算法无法把最开始的点置为零,因此每次dfs之前要置零
visit[j]=0;
visit[i]=1;
dfs(i,1,0);
}
}
cout<<result;
}