题目大意:
  给你一个$n(n\leq 2\times 10^4)$个点,$m(m\leq 2\times 10^5)$条边的带边权的连通图。其中有$k(k\leq 20)$个关键点。关键点之间有$g$条拓扑结构的依赖关系,每条依赖关系$(u,v)$描述点$v$依赖于点$u$,即点$u$必须在点$v$之前出现。若同时存在依赖关系$(u,v)$和$(v,w)$,则有依赖关系$(u,w)$。每个点可以经过多次,经过的可以不满足依赖关系。求一条从$1$到$n$的最短的路径,满足每个关键点至少有一次被经过时满足了依赖关系。

思路:
  状压DP。
  首先用Floyd预处理每个关键点依赖的点集$pre[i]$。然后用Dijkstra求出点$1$和每个关键点作为起点的单源最短路。
  用$f[S][i]$表示已满足依赖关系的点集为$S$,当前路径上,最后一个结点为$i$。
  预处理$f[i][i]=\left\{\begin{aligned}dis[1][i]&&{pre[i]=\varnothing}\\\infty&&pre[i]\neq\varnothing\end{aligned}\right.$。
  转移方程为$f[S\bigcup i][i]=\min\{f[S][j]+dis[i][j]\mid i\notin S\land pre[i]\in S\}$。
  答案$ans=\min{f[U][i]+dis[i][n]}$。
  Floyd$O(k^3)$,配对堆优化Dijkstra$O(m+n\log n)$,动态规划$O(2^kk^2)$时间复杂度为$O(k^3+m+n\log n+2^kk^2)$。空间复杂度$O(2^kk)$。
  在BZOJ上跑了9068 MS,内存89980 KB,Rank 2。但是POI原题内存是64 MB。
  一种卡内存的方法是压缩一下状态,因为$f[S][i]$中$S$一定包括$i$,因此我们可以把$i$这一位去掉,然后把大于$i$的位往前移。空间除以一个常数,可以卡过。
  还有一种做法是根据$S$中元素个数,将DP数组进行滚动,空间复杂度为$O(n\binom{k}{\lceil\frac{k}{2}\rceil})$。

 #include<cstdio>
#include<cctype>
#include<vector>
#include<climits>
#include<functional>
#include<ext/pb_ds/priority_queue.hpp>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
const int N=,K=;
const int inf=INT_MAX;
struct Edge {
int to,w;
};
std::vector<Edge> e[N];
inline void add_edge(const int &u,const int &v,const int &w) {
e[u].push_back((Edge){v,w});
e[v].push_back((Edge){u,w});
}
bool b[K][K];
int n,m,k,pre[K],dis0[N],dis[K][N],f[<<K][K];
struct Vertex {
int id,dis;
bool operator > (const Vertex &another) const {
return dis>another.dis;
}
};
void dijkstra(const int &s,int dis[]) {
static __gnu_pbds::priority_queue<Vertex,std::greater<Vertex> > q;
static __gnu_pbds::priority_queue<Vertex,std::greater<Vertex> >::point_iterator p[N];
for(register int i=;i<=n;i++) {
p[i]=q.push((Vertex){i,dis[i]=i==s?:inf});
}
while(!q.empty()) {
const int x=q.top().id;
q.pop();
for(register unsigned i=;i<e[x].size();i++) {
const int &y=e[x][i].to,&w=e[x][i].w;
if(dis[x]+w<dis[y]) {
q.modify(p[y],(Vertex){y,dis[y]=dis[x]+w});
}
}
}
}
int main() {
n=getint(),m=getint(),k=getint();
for(register int i=;i<m;i++) {
const int u=getint(),v=getint(),w=getint();
add_edge(u,v,w);
}
if(k==) {
dijkstra(,dis0);
printf("%d\n",dis0[n]);
return ;
}
for(register int i=getint();i;i--) {
const int u=getint(),v=getint();
b[u-][v-]=true;
}
for(register int l=;l<k;l++) {
for(register int i=;i<k;i++) {
if(i==l||!b[i][l]) continue;
for(register int j=;j<k;j++) {
if(j==l||j==i||!b[l][j]) continue;
b[i][j]=true;
}
}
}
for(register int i=;i<k;i++) {
for(register int j=;j<k;j++) {
if(b[i][j]) pre[j]|=<<i;
}
}
dijkstra(,dis0);
for(register int i=;i<=k+;i++) {
dijkstra(i,dis[i-]);
}
for(register int state=;state<<<k;state++) {
for(register int i=;i<k;i++) {
f[state][i]=inf;
}
}
for(register int i=;i<k;i++) {
if(!pre[i]) f[<<i][i]=dis0[i+];
}
for(register int state=;state<<<k;state++) {
for(register int i=;i<k;i++) {
if(!(state&(<<i))&&(state&pre[i])==pre[i]) {
for(register int j=;j<k;j++) {
if(f[state][j]!=inf) {
f[state^(<<i)][i]=std::min(f[state^(<<i)][i],f[state][j]+dis[j][i+]);
}
}
}
}
}
int ans=inf;
for(register int i=;i<k;i++) {
if(f[(<<k)-][i]==inf) continue;
ans=std::min(ans,f[(<<k)-][i]+dis[i][n]);
}
printf("%d\n",ans);
return ;
}

[POI2007]Tourist Attractions的更多相关文章

  1. [POI2007]ATR-Tourist Attractions [TPLY]

    [POI2007]ATR-Tourist Attractions 题目链接(https://www.luogu.org/problemnew/show/P3451) 这种稠密图还是建议你不要跑spfa ...

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

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

  3. LYDSY模拟赛day1 Tourist Attractions

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

  4. 解题:POI 2007 Tourist Attractions

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

  5. [POI2007]ATR-Tourist Attractions

    题目大意:一个无向图,从$1$到$n$,要求必须经过$2,3,\dots,k+1$,给出一些限制关系,要求在经过$v\leq k+1$之前必须经过$u\leq k+1$,求最短路 题解:预处理出$1\ ...

  6. 【JZOJ4857】Tourist Attractions(Bitset)

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

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

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

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

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

  9. D. 旅游景点 Tourist Attractions 状压DP

    题目描述 FGD想从成都去上海旅游.在旅途中他希望经过一些城市并在那里欣赏风景,品尝风味小吃或者做其他的有趣的事情.经过这些城市的顺序不是完全随意的,比如说FGD 不希望在刚吃过一顿大餐之后立刻去下一 ...

随机推荐

  1. PEAR DB 事务相关

    1.autoCommit().commit().rollback() function autoCommit($onoff=false) 指定是否自动提交事务.有的后端数据库不支持. function ...

  2. airTest 实战之 -- 【征途】自动打怪回城卖物品

    airTest是一个跨平台的.基于图像识别的UI自动化测试框架,适用于游戏和App,支持平台有Windows.Android和iOS 官方文档: http://airtest.netease.com/ ...

  3. 【AtCoder】AGC012

    AGC012 A - AtCoder Group Contest 从最后开始间隔着取就行 #include <bits/stdc++.h> #define fi first #define ...

  4. 怎么查看linux系统是32位还是64位

    1.#uname -a如果有x86_64就是64位的,没有就是32位的 这是64位的 # uname -a Linux desktop 2.6.35-23-generic #20-Ubuntu SMP ...

  5. saltstack 实现haproxy+keepalived

    1.目录结构规划如下 mkdir -p /srv/salt/prod/haproxy mkdir -p /srv/salt/prod/keepalived mkdir -p /srv/salt/pro ...

  6. html中<a href> </a>的用法

    一.绝对跳转    <a href="http://www.baidu.com/">百度</a> 二.相对跳转有如下方式,需要了解(以下的例子中,分别以你的 ...

  7. JSON.stringify与jQuery.parseJSON

    1.JSON.stringify,这个函数的作用主要是为了系列化对象的.(或者说是将原来的对象转换为字符串的,如json对象): 首先定义一个json对象,var jsonObject = { &qu ...

  8. 图表绘制工具--Matplotlib 2

    ''' [课程3.] 基本图表绘制 plt.plot() 图表类别:线形图.柱状图.密度图,以横纵坐标两个维度为主 同时可延展出多种其他图表样式 plt.plot(kind='line', ax=No ...

  9. Ubuntu14连接MySql报错“can't connect to local mysql server through socket '/var/run/mysqld/mysqld.sock'”

    起因:我在Ubuntu14 64位系统中安装mysql后,后来通过mysql -u用户名 -p密码 的命令连接 Mysql数据库时,报错"can't connect to local mys ...

  10. linux内核分析之缺页中断【转】

    转自:http://blog.csdn.net/bullbat/article/details/7108402 linux缺页异常程序必须能够区分由编程引起的异常以及由引用属于进程地址空间但还尚未分配 ...