P1294 高手去散步(洛谷)
题目背景
高手最近谈恋爱了。不过是单相思。“即使是单相思,也是完整的爱情”,高手从未放弃对它的追求。今天,这个阳光明媚的早晨,太阳从西边缓缓升起。于是它找到高手,希望在晨读开始之前和高手一起在鳌头山上一起散步。高手当然不会放弃这次梦寐以求的机会,他已经准备好了一切。
题目描述
鳌头山上有n个观景点,观景点两两之间有游步道共m条。高手的那个它,不喜欢太刺激的过程,因此那些没有路的观景点高手是不会选择去的。另外,她也不喜欢去同一个观景点一次以上。而高手想让他们在一起的路程最长(观景时它不会理高手),已知高手的穿梭机可以让他们在任意一个观景点出发,也在任意一个观景点结束。
输入格式
第一行,两个用空格隔开的整数n、m. 之后m行,为每条游步道的信息:两端观景点编号、长度。
输出格式
一个整数,表示他们最长相伴的路程。
输入输出样例
输入 #1
4 6
1 2 10
2 3 20
3 4 30
4 1 40
1 3 50
2 4 60
输出 #1
150
说明/提示
对于100%的数据:n≤20,m≤50,保证观景点两两之间不会有多条游步道连接.
题解思路:
这是一个比较基本的深搜问题,思路很清晰。关键在于如何存储这些信息方便我们搜索和如何实现不去同一个景点一次以上、如何搜到最长路。
1.对于存储问题,这里采用的是邻接矩阵(实际上就是二维数组),如a[i][j]中储存第i个景点和第j个景点的路径长度,若两景点间不存在路设置为0。
2.对于不去同一个景点一次以上,走过的景点标1,防止再次被搜索,这样就避免了搜索后在被搜索的可能,直到退出当前景点搜索时才重新标0。
3.对于最长路来看,由于每次搜索都是从某个固定起点开始搜的,这样并不能保证当前起点就能搜出所有路径中最长的那条,因此我们以每个点为起点搜一遍,并不断更新最大值路径。
代码:
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std; 5 6 //可以用一个二元数组来存放关系 7 int map[51][51]={0}; 8 int n,m; 9 int flag[21]={0}; //0表示未访问过,1表示已经访问了 10 int maxx=0; //最大路程 11 void dfs(int cur,int sum){ 12 flag[cur]=1; //表示访问过 13 // cout<<"cur;"<<cur<<"sum:"<<sum<<endl; 14 15 int ff=0; 16 for(int i=1;i<=n;i++){ 17 if(flag[i]==1) continue; //跳过不去 18 if(map[cur][i]!=0){ 19 ff=1; //标志着还有点可以继续下去 20 dfs(i,sum+map[cur][i]); 21 flag[i]=0; //回溯,表示访问后回退时标志取消 22 } 23 } 24 if(ff==0){ //代表无路可走因此此处更新最大值,以避免景点重复访问的情况 25 maxx=max(maxx,sum); 26 } 27 return ; 28 } 29 int main(){ 30 cin>>n>>m; 31 32 for(int k=1;k<=m;k++){ 33 int t1=0,t2=0; 34 cin>>t1>>t2; 35 cin>>map[t1][t2]; //只录入一般,判断时可用map[i][j]或map[j][i] 36 map[t2][t1]=map[t1][t2]; 37 } 38 39 40 for(int i=1;i<=n;i++){ 41 memset(flag,0,sizeof(flag)); //每次搜索清空标志 42 dfs(i,0); //从景点i开始搜索 43 } 44 cout<<maxx; 45 46 return 0; 47 }