Tyvj P1288 飘飘乎居士取能量块

24 篇文章 0 订阅

背景

9月21日,pink生日;9月22日,lina生日;9月23日,轮到到飘飘乎居士(狂欢吧,(*^__^*) 嘻嘻……)。

描述

  9月21日,今天是pink的生日,飘飘乎居士当然要去别人的领土大闹一番啦!
  为了收集更多的能量到pink家大闹,飘飘乎居士准备从后花园中取出自己多年积攒的p个能量块。后花园一共被划分n个地区,能量块被分散在里面,现在飘飘乎居士拿出地图,发现自己站在1的地方,而他要做的就是用最短的路程把所有的能量块取出,并且最后走到位于n的出口处,而飘飘乎居士一直是个懒人,他想知道最少要走多少路程才能够取到所有的能量块,并且走到出口

输入格式

第一行一个正整数n,表示花园被划分成了n个地区
接下来一个n*n的矩阵,代表个点之间的相互距离,数据保证从i走到i没有路程
在下来一个整数p,表示一共有p个能量块
接下来一行,表示各个能量块的位置,数据保证1和n没有能量块,且每个地区最多一个能量块
对于所有的数据 0<n<=100  0<=P<=10 任意两点的距离为一个小于1000的正整数

输出格式

一个数,飘飘乎居士所要行走的最小距离

测试样例1

输入


0 10 1 
3 0 5 
1 2 0 

2

输出

7

备注

花园被分为3个地区,在2号地区有能量块,飘飘乎居士行走的路线如下
1->3->2->1->3
行走的总路程为7,也就是最后的答案。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

似乎自从学过以后这是我第一次写floyd?

主要就是floyed求一下点之间的最短距离,然后用(神奇的)next_permutation求出总的最小路程~

next_permutation用来求全排列~


#include<cstdio>
#include<algorithm>
using namespace std;
#define min(u,v) u<v ? u:v

int n,p,dis[105][105],a[105],minn,num;

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	  for(int j=1;j<=n;j++) scanf("%d",&dis[i][j]);
	scanf("%d",&p);
	for(int i=1;i<=p;i++) scanf("%d",&a[i]);
	for(int i=1;i<=n;i++)
	  for(int j=1;j<=n;j++)
	    for(int k=1;k<=n;k++) dis[j][k]=min(dis[j][k],(dis[j][i]+dis[i][k]));
	sort(a+1,a+p+1);a[0]=1;
	for(int i=1;i<=p;i++) num+=dis[a[i-1]][a[i]];
	num+=dis[a[p]][n];
	minn=num;
	while(next_permutation(a+1,a+p+1))
	{
		num=0;
		for(int i=1;i<=p;i++) num+=dis[a[i-1]][a[i]];
		num+=dis[a[p]][n];minn=min(minn,num);
	}
	printf("%d\n",minn);
	return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值