P1288 飘飘乎居士取能量块
时间: 1000ms / 空间: 131072KiB / Java类名: Main

背景

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

输入

3

0 10 1

3 0 5

1 2 0

1

2

输出

7

备注

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

题解:

裸状压。

 #include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define max(a, b) a > b ? a : b
#define min(a, b) a < b ? a : b inline void read(int &x)
{
x = ;char ch = getchar();char c = ch;
while(ch > '' || ch < '')c = ch, ch = getchar();
while(ch <= '' && ch >= '')x = x * + ch - '', ch = getchar();
if(c == '-')x = -x;
} const int MAXN = + ;
const int MAXP = + ; int g[MAXN][MAXN], n, p, dir[MAXP], ok1, ok2;
int f[MAXN][ << MAXP]; int main()
{
memset(f, 0X3f, sizeof(f));
read(n);
for(register int i = ;i <= n;++ i)
for(register int j = ;j <= n;++ j)
read(g[i][j]);
for(register int k = ;k <= n;++ k)
for(register int i = ;i <= n;++ i)
for(register int j = ;j <= n;++ j)
g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
read(p);
for(register int i = ;i <= p;++ i)
{
read(dir[i]);
if(dir[i] == ) ok1 = true;
else if(dir[i] == n) ok2= true;
}
if(!ok1) dir[++ p] = ;
if(!ok2) dir[++ p] = n; std::sort(dir + , dir + + p);
f[][] = ;
//f[i][S]表示从1出发走到点i,取到了S的能量块的最短路径
register int M = << p, now, tmp;
for(register int S = ;S < M;++ S)
{
for(register int i = ;i <= p;++ i)
{
if(!(S & ( << (i - ))))continue;
now = dir[i];
for(register int j = ;j <= p;++ j)
{
if(i == j)continue;
if(!(S & ( << (j - ))))continue;
tmp = dir[j];
f[now][S] = min(f[now][S], f[tmp][S ^ ( << (i - ))] + g[tmp][now]);
}
}
}
printf("%d", f[n][M - ]);
return ;
}

tyvj1288

最新文章

  1. 登录框密码框input框禁止复制、粘贴、剪切和右键功能
  2. codeforces 496B. Secret Combination 解题报告
  3. storm的并发和消息保障性
  4. ERROR 1044 (42000) ERROR 1142 (42000): SELECT command denied to user &#39;&#39;@&#39;localhost&#39; for table &#39;user&#39;
  5. exists与in的使用与区别
  6. Android Wear开发 - 数据通讯 - 第二节 : 数据的发送与接收
  7. python实现tailf
  8. Friendship of Frog(水题)
  9. Nginx http_user_agent 防御 ab 等
  10. Linux之用户管理--初级上
  11. 【朝花夕拾】Android安全之(一)权限篇
  12. 编写基于Property-based的单元测试
  13. 基于element ui的级联选择器组件实现的分类后台接口
  14. PHP7 学习笔记(十七)变量函数 - unset
  15. archlinux下我的软件列表
  16. Bootstrap3基础 栅格系统 1行最多12列
  17. servlet的运行机制,转发和重定向
  18. jdbc导致的问题
  19. Python学习笔记-输入与输出
  20. MySQL读取配置文件的顺序、启动方式、启动原理

热门文章

  1. Jqgrid 序号列宽度调整
  2. vue-admin-template模板添加tagsview
  3. C/C++操作SQLite
  4. [HEOI2016/TJOI2016]排序 线段树+二分
  5. 【codeforces 505C】Mr.Kitayuta,the Treasure Hunter
  6. Extjs4 的一些语法 持续更新中
  7. phpStrom编辑器 通过 git 提交代码到 gitlab
  8. PAT甲级——A1012 The Best Rank
  9. Chapter 1 线性表
  10. 在Linux中常用的启动引导工具:grub和lilo