资源限制
内存限制: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
#include<iostream>
#include<math.h>
#include<cstring>
using namespace std;
const int N=35;
int mp[N][N];
int visit[N];//妹妹要去的景点
bool vis[N];//已访问的景点
int ans=0x3f3f3f3f;
int cnt=0;//实际的景点数
int n;//n个点
//深度遍历求游览计划的最短时间
void dfs(int pos,int count,int sum){//pos为当前的景点,count为已访问的景点数,sum为时间 if(count==cnt){ans=min(ans,sum);return;}for(int i=1;i<=n;i++){if(visit[i]&&!vis[i]&&sum<ans){vis[i]=true;mp[0][i]=0;dfs(i,count+1,sum+mp[pos][i]);vis[i]=false;}}
}
int main(){ cin>>n;memset(mp,0x3f,sizeof(mp));for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){cin>>mp[i][j]; }} int m;//要去的景点数 cin>>m;for(int i=1;i<=m;i++){int x;cin>>x;if(visit[x]==0) cnt++;visit[x]=1;} for(int k=1;k<=n;k++){//通过点k中转 for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){if(i!=j&&i!=k&&k!=j&&mp[i][j]>mp[i][k]+mp[k][j]){mp[i][j]=mp[i][k]+mp[k][j];}}} }dfs(0,0,0);cout<<ans<<endl;return 0;
}
思路:先使用Floyed算法求每个点之间的最短时间,然后用dfs将访问景点的顺序进行全排列(即遍历每一种情况)