题解

这里的做法是卡空间的做法,相比于滚动数组,这种做法因为没有三维数组寻址的大常数,所以较快。

在普通的做法中,\(dp[state][i]\) 表示以 \(i\) 结尾,那么 \(state\) 一定是包含 \(i\) 的状态,所以在 \(state\) 中可以省掉 \(i\) 这一位

所以 \(cost=(k+1)×2^{k-1}×4kb\) ,大约为 \(42MB\)

注:本题用 \(spfa\) 会比 \(dijkstra\) 快很多

Code:
#include<bits/stdc++.h>
#define ri register signed
#define p(i) ++i
using namespace std;
namespace IO{
char buf[1<<21],*p1=buf,*p2=buf;
#define gc() p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++
template<typename T>inline void read(T &x) {
ri f=1;x=0;register char ch=gc();
while(ch<'0'||ch>'9') {if (ch=='-') f=0;ch=gc();}
while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48);ch=gc();}
x=f?x:-x;
}
}
using IO::read;
namespace nanfeng{
#define node(x,y) (node){x,y}
#define cmax(x,y) ((x)>(y)?(x):(y))
#define cmin(x,y) ((x)>(y)?(y):(x))
#define FI FILE *IN
#define FO FILE *OUT
static const int N=2e4+7,M=2e5+7;
int first[N],dp[1<<19][21],pre[21],dis[21][N],vis[N],n,m,q,k,t=2,S;
struct edge{int v,w,nxt;}e[M<<1];
struct node{int x,dis;};
priority_queue<node> que;
inline int operator<(const node &n1,const node &n2) {return n1.dis>n2.dis;}
inline void add(int u,int v,int w) {
e[t].v=v,e[t].w=w,e[t].nxt=first[u],first[u]=t++;
e[t].v=u,e[t].w=w,e[t].nxt=first[v],first[v]=t++;
}
inline void dij(int rt){
memset(vis,0,sizeof(vis));
memset(dis[rt-1],0x3f,sizeof(dis[rt-1]));
dis[rt-1][rt-1]=0;
que.push(node(rt,0));rt-=1;
while(!que.empty()) {
int x(que.top().x),dist(que.top().dis);
que.pop();
if (vis[x]) continue;
vis[x]=1;
for (ri i(first[x]),v;i;i=e[i].nxt) {
if (dis[rt][v=e[i].v-1]>dist+e[i].w) {
dis[rt][v]=dist+e[i].w;
que.push(node(v+1,dis[rt][v]));
}
}
}
}
inline int calc(int x,int l) {
if ((1<<l)>x) return x;
ri tmp=x&((1<<l)-1);
return (x>>(l+1))<<l|tmp;
}
inline int main() {
// FI=freopen("nanfeng.in","r",stdin);
// FO=freopen("nanfeng.txt","w",stdout);
read(n),read(m),read(k);
for (ri i(1),u,v,w;i<=m;p(i)) read(u),read(v),read(w),add(u,v,w);
read(q);
for (ri i(1),r,s;i<=q;p(i)) {
read(r);read(s);
pre[s-2]|=1<<(r-2);
}
for (ri i(1);i<=k+1;p(i)) dij(i);
if (!k) {printf("%d\n",dis[0][n-1]);return 0;}
memset(dp,0x3f,sizeof(dp));
dp[0][0]=0;
for (ri i(1);i<=k;p(i)) if (!pre[i-1]) dp[0][i]=dis[0][i];
S=(1<<k)-1;
for (ri i(1);i<=S;p(i)) {
for (ri j(0);j<k;p(j)) {
if (!((1<<j)&i)) continue;
ri tmp1=calc(i,j);
for (ri l(0);l<k;p(l)) {
if (!(i&(1<<l))&&((i&pre[l])==pre[l])) {
ri tmp2=calc(i,l);
dp[tmp2][l+1]=cmin(dp[tmp1][j+1]+dis[j+1][l+1],dp[tmp2][l+1]);
}
}
}
}
ri ans=INT_MAX;
for (ri i(1),tmp;i<=k;p(i)) {
tmp=calc(S,i-1);
ans=cmin(ans,dp[tmp][i]+dis[i][n-1]);
}
printf("%d\n",ans);
return 0;
}
}
int main() {return nanfeng::main();}

题解 P3451 [POI2007]ATR-Tourist Attractions的更多相关文章

  1. csp-s模拟48,49 Tourist Attractions,养花,画作题解

    题面:https://www.cnblogs.com/Juve/articles/11569010.html Tourist Attractions: 暴力当然是dfs四层 优化一下,固定两个点,答案 ...

  2. 【题解】Uoj#30 Tourist(广义圆方树+树上全家桶)

    [题解]Uoj#30 Tourist(广义圆方树+树上全家桶) 名字听起来很霸气其实算法很简单.... 仙人掌上的普通圆方树是普及题,但是广义圆方树虽然很直观但是有很多地方值得深思 说一下算法的流程: ...

  3. [POI2007]Tourist Attractions

    题目大意: 给你一个$n(n\leq 2\times 10^4)$个点,$m(m\leq 2\times 10^5)$条边的带边权的连通图.其中有$k(k\leq 20)$个关键点.关键点之间有$g$ ...

  4. 旅游景点 Tourist Attractions 题解

    题面在这里 再次破了纪录,连做了3天... 让我们从头来一点一点分析 1.预处理 先看题面,乍一看貌似是个图论题,有n个点m条边,给定一些必须经过的点和强制经过顺序,求一条最短路 我们发现n和m都比较 ...

  5. [CSP-S模拟测试]:Tourist Attractions(简单图论+bitset)

    题目描述 在美丽的比特镇一共有$n$个景区,编号依次为$1$到$n$,它们之间通过若干条双向道路连接.$Byteasar$慕名来到了比特镇旅游,不过由于昂贵的门票费,他只能负担起$4$个景区的门票费. ...

  6. 比特镇旅游(Tourist Attractions)【暴力+Bitset 附Bitset用法】

    Online Judge:NOIP2016十连测第一场 T2 Label:暴力,Bitset 题目描述 在美丽的比特镇一共有n个景区,编号依次为1到n,它们之间通过若干条双向道路连接. Byteasa ...

  7. LYDSY模拟赛day1 Tourist Attractions

    /* 假设路径是 a − b − c − d,考虑枚举中间这条边 b − c,计 算有多少可行的 a 和 d. 设 degx 表示点 x 的度数,那么边 b − c 对答案的贡献为 (degb − 1 ...

  8. 解题:POI 2007 Tourist Attractions

    题面 事实上这份代码在洛谷过不去,因为好像要用到一些压缩空间的技巧,我并不想(hui)写(捂脸) 先预处理$1$到$k+1$这些点之间相互的最短路和它们到终点的最短路,并记录下每个点能够转移到时的状态 ...

  9. 【JZOJ4857】Tourist Attractions(Bitset)

    题意:给定一个n个点的无向图,求这个图中有多少条长度为4的简单路径. n<=1500 思路: #include<map> #include<set> #include&l ...

随机推荐

  1. buu signin

    一.拖入ida,来静态分析F5大法好 要注意的点: 1._gmz_init_set_str() 这个函数,也是看师傅的wp,学到的,以后还是得多google, 本质上是这个函数: int mpz_in ...

  2. [NOI2009] 诗人小G [题解]

    诗人小G 题目大意 给出 \(n\) 个长度不超过 \(30\) 的句子,要求你对其进行排版. 对于每一行,有一个规定的行标准长度 \(L\) ,每一行的不协调度等于该行的实际长度与行标准长度差的绝对 ...

  3. C语言:缓冲区

    缓冲区(Buffer)又称为缓存(Cache),是内存空间的一部分.也就是说,计算机在内存中预留了一定的存储空间,用来暂时保存输入或输出的数据,这部分预留的空间就叫做缓冲区(缓存).有时候,从键盘输入 ...

  4. Unittest方法 -- 用例执行顺序

    import unittestfrom selenium import webdriverclass F4(unittest.TestCase): @classmethod def setUpClas ...

  5. 微信小程序云开发-云存储-获取带图片的商品列表

    一.将商品图片上传至云存储 如下图,已准备5张商品图片,并且已经将商品图片上传至云存储  二.数据库表添加图片字段 在数据库表goods添加字段image,该字段用来存储图片的url信息 image在 ...

  6. Cesium局部区域精细瓦片数据下载技巧

    当Cesium加载局部的目标地区(如中国某个市)的0-18层或更高层数据时,当缩小到zoom较小时可能地球有部分区域(如南半球或左半球)无瓦片覆盖. 为使得整个地球有瓦片覆盖,可利用以下技巧下载瓦片: ...

  7. 选择排序(selection_sort)——Python实现

      # 选择排序 # 作用:对给出的n个顺序不定的数进行排序 # 输入:任意数组A # 输出:按顺序排列的数组A # 时间复杂度 (n(n-1))/2 # 选择排序 # 第一趟:选择第一个元素,依次与 ...

  8. jvm源码解读--07 创建 fixup_mirrors

    通过前面的分析,创建的insttanceKlass 都没放入了java_lang_Class::fixup_mirror_list()这里类的数组里面了,所有的instance列举如下 ------- ...

  9. Python实用案例,Python脚本,Python实现文件自动归类

    前言: 今天我们就利用Python脚本实现文件自动归类吧.直接开整~ 预备知识 这个脚本实现比较简单,我把涉及的知识点列了出来. 1.相对路径.绝对路径,绝对路径就是最完整的路径. 'D:/code/ ...

  10. SpringBoot自动装配-Condition

    1. 简介 @Conditional注解在Spring4.0中引入,其主要作用就是判断条件是否满足,从而决定是否初始化并向容器注册Bean. 2. 定义 2.1 @Conditional @Condi ...