最短的旅程
2016-01-01 18:11
381 查看
在Byteland有n个城市(编号从1到n),它们之间通过双向的道路相连。Byteland的国王并不大方,所以,那里只有n -1条道路,但是,它们的连接方式使得从任意城市都可以走到其他的任何城市。
一天,starhder到了编号为k的城市。他计划从城市k开始,游遍城市m1,m2,m3,……,mj(不一定要按这个顺序旅游),其中j个城市都是不同的,并且也与k不同。Starhder—— 就像每一个旅行家一样,携带的钱总是有限的,所以,他要以最短的路程旅行完所有的城市(从城市k开始)。 于是,他请你帮助计算一下,旅游完上述的城市最短需要多少路程。
输入参数
第一行输入两个整数,即上文中的n和k,以一个空格隔开。下面的n-1行每行描述一条路,每行输入3个整数ai,bi,di,相邻两个数用一个空格隔开(1<= ai,bi<= n,1<= di<= 1000),ai和bi是用道路直接相连的城市编号,di是这条道路的长度。 第n + 1行输入一个整数j,是starhder要旅游的城市数(1<=
j <= n - 1),接下来一行包含j个不同的整数,即m1,m2,……,mj,每两个相邻的整数用一个空格隔开,表示starhder想要去的城市。(1<= mt<=n,mt
不等于k)。
输出参数
输出只有一行,包含一个整数:starhder旅游的最短路程。
样例输入
4 2
1 2 1
4 2 2
2 3 3
2
1 3
样例输出
5
思路:题目中说n个节点总共有n-1条路,所以是一个棵树。先用Floyd求出各节点之间的最短路径,然后将不用去的节点去掉,之后就可以只用剩下的节点求出所要去的最短路径。我用的是暴力搜索,复杂度有点高。
一天,starhder到了编号为k的城市。他计划从城市k开始,游遍城市m1,m2,m3,……,mj(不一定要按这个顺序旅游),其中j个城市都是不同的,并且也与k不同。Starhder—— 就像每一个旅行家一样,携带的钱总是有限的,所以,他要以最短的路程旅行完所有的城市(从城市k开始)。 于是,他请你帮助计算一下,旅游完上述的城市最短需要多少路程。
输入参数
第一行输入两个整数,即上文中的n和k,以一个空格隔开。下面的n-1行每行描述一条路,每行输入3个整数ai,bi,di,相邻两个数用一个空格隔开(1<= ai,bi<= n,1<= di<= 1000),ai和bi是用道路直接相连的城市编号,di是这条道路的长度。 第n + 1行输入一个整数j,是starhder要旅游的城市数(1<=
j <= n - 1),接下来一行包含j个不同的整数,即m1,m2,……,mj,每两个相邻的整数用一个空格隔开,表示starhder想要去的城市。(1<= mt<=n,mt
不等于k)。
输出参数
输出只有一行,包含一个整数:starhder旅游的最短路程。
样例输入
4 2
1 2 1
4 2 2
2 3 3
2
1 3
样例输出
5
思路:题目中说n个节点总共有n-1条路,所以是一个棵树。先用Floyd求出各节点之间的最短路径,然后将不用去的节点去掉,之后就可以只用剩下的节点求出所要去的最短路径。我用的是暴力搜索,复杂度有点高。
#include <iostream> #include <cstdio> #include <cstring> #include <vector> using namespace std; #define M 1050 #define inf 0xfffffff int map[M][M],n,k,city; bool go[M]; //go[i]表示去没去过城市i int ans; void init() { for(int i=1;i<=n;i++) { for(int j=1;j<=i;j++) map[i][j]=map[j][i]=inf; go[i]=1; //初始化都是去过的,然后输入想去哪些城市,把他们变成没去过 } } void floyd() //先求出各城市之间的最短路径 { for(int t=1;t<=n;t++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) map[i][j]=min(map[i][j],map[i][t]+map[t][j]); } void dfs(int st,int num,int sum) //用已知最短路径的图搜索求出最小的路程 { if(num==city) { ans=min(ans,sum); return; } for(int j=1;j<=n;j++) { if(!go[j]) { go[j]=1; dfs(j,num+1,sum+map[st][j]); go[j]=0; //每个路径不能互相影响,所以不能忘记要复制回来 } } } int main() { int s,e,d; while(~scanf("%d%d",&n,&k)) { init(); ans=inf; for(int i=1;i<=n-1;i++) { scanf("%d%d%d",&s,&e,&d); map[s][e]=map[e][s]=d; } floyd(); scanf("%d",&city); for(int i=0;i<city;i++) { scanf("%d",&s); go[s]=0; } /* for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) printf("%d ",map[i][j]); printf("\n"); }*/ dfs(k,0,0); printf("%d\n",ans); } return 0; } /* 6 2 1 2 1 1 3 1 2 4 2 3 5 2 5 6 2 3 3 4 5 */
相关文章推荐
- git初探
- android view的生命周期
- Android学习笔记之横向二级菜单实现
- CSS3 笔记五(Buttons)
- liunx清理磁盘du -h --max-depth=1 /data/*
- mjpg-streamer摄像头远程传输UVC
- LA3882(约瑟夫问题及变形)
- 常用Myeclipse快捷键整理
- android开发中使用高德地图出现的一些问题
- 关于null+2的问题
- 写一些脚本的心得总结系列第2篇-----历史数据迁移到分表
- 鸟哥Linux私房菜知识点总结6到7章
- RHEL6和RHEL7系统运行级别设置以及切换
- 自定义简化版本的vector容器
- Android5.1 联系人号码搜索过程缓存原理
- C 语言之字符串处理函数一 -2016.01.01
- iPhone、iPad强制关机
- wind 7 配置示图
- ListView万能适配器
- vim+clipboard+vim-gui(gvim)源码编译