[TK] Tourist Attractions
题目描述
给出一张有 \(n\) 个点 \(m\) 条边的无向图,每条边有边权。
你需要找一条从 \(1\) 到 \(n\) 的最短路径,并且这条路径在满足给出的 \(g\) 个限制的情况下可以在所有编号从 \(2\) 到 \(k+1\) 的点上停留过。
每个限制条件形如 \(r_i, s_i\),表示停留在 \(s_i\) 之前必须先在 \(r_i\) 停留过。
注意,这里的停留不是指经过。
解法分析
对于这道题的状压. 我们考虑枚举 "现在已经在哪些点停留" 这样一种状态. 然后去寻找每一个当前未停留的点,考虑这个点的前置节点是否全部已经停留,如果是,那么枚举每一个已在集合内的节点,尝试把这个点通过某条边放入集合内,进行状态转移.
那么我们需要进行状态压缩的有两个东西: 现在已有的点的情况 (用于枚举) 和每个点的前置节点情况 (用于判断).
最后需要我们输出的就是在全部节点停留情况下的状态.
这道题的主要思路:
for(int i=1;i<=(1<<k)-1;++i){
//all possible chance
for(int j=0;j<=k-1;++j){ //node
if(i&(1<<j)){
//if this node in this chance
for(int hdk=0;hdk<=k-1;++hdk){
//then try to add a node
if(!(i&(1<<hdk))&&((i|r[hdk+2])==i)){
//if find a node not in chance and can be placed
update();
}
//then do the change. why it's +2 is because I store 3 in position 1.(1 and 2 is no need)
}
}
}
}
那么,为了更新已选中的点的距离,我们需要知道从任意点到另一点的距离,也就是跑一边全源最短路.
我们定义 \(dis[i][j]\) 为全源最短路下的 \(i,j\) 最短距离. \(r[i]\) 表示 \(i\) 的全部前置节点的状压表示. \(f[i][j]\) 表示在已经选择 \(i\) (状压表示) 这些节点的情况下,且最后一个选中的节点为 \(j\) 的最短路径长度. 那么我们有:
\]
那么我们怎么表示 \(i\ add\ k\) 呢. 其实只需要将 \(i\) 中的 \(k\) 点的位置置为 \(1\). 也就是做一次或运算.
这题我也不知道它卡什么. 我存图的 vector 滚动数组会比前向星小很多,而 DIJ 又比 SPFA 快很多. 总之按对的来吧.
代码实现
#include<bits/stdc++.h>
using namespace std;
int n,m,k;
struct edge{
int to,w;
};
struct node{
int id,dis;
bool operator<(const node A)const{
return dis>A.dis;
}
};
priority_queue<node> q;
vector<edge> e[20001];
int dis[31][20001]; //root i's dis j
bool vis[20001];
void dij(int s){
memset(vis,false,sizeof vis);
for(int i=1;i<=n;++i){
dis[s][i]=1000000000;
}
while(!q.empty()) q.pop();
dis[s][s]=0;
q.push(node{s,0});
while(!q.empty()){
node u=q.top();
q.pop();
if(vis[u.id]) continue;
vis[u.id]=true;
for(edge i:e[u.id]){
if(dis[s][i.to]>dis[s][u.id]+i.w){
dis[s][i.to]=dis[s][u.id]+i.w;
q.push(node{i.to,dis[s][i.to]});
}
}
}
}
int f[1<<20][31],r[31],ans=1000000000; //1=zt(which nodes been chose) 2=node //r= mustfore
int main(){
cin>>n>>m>>k;
for(int i=1;i<=m;++i){
int a,b,c;
cin>>a>>b>>c;
e[a].push_back(edge{b,c});
e[b].push_back(edge{a,c});
}
if(k==0){
dij(1);
cout<<dis[1][n];
return 0;
}
int q;
cin>>q;
while(q--){
int a,b;
cin>>a>>b;
r[b]+=(1<<(a-2));//
}
for(int i=1;i<=k+1;++i){
dij(i);
}
for(int i=0;i<=(1<<k)-1;++i){
for(int j=1;j<=k+1;++j){
f[i][j]=1000000000;
}
}
f[0][1]=0;
for(int i=2;i<=k+1;++i){
if(!r[i]){ //if this point hasn't any requires.
f[1<<(i-2)][i]=dis[1][i];
}
}
for(int i=1;i<=(1<<k)-1;++i){ //all possible chance
for(int j=0;j<=k-1;++j){ //node
if(i&(1<<j)){ //if this node in this chance
for(int hdk=0;hdk<=k-1;++hdk){ //then try to add a node
if(!(i&(1<<hdk))&&((i|r[hdk+2])==i)){ //if find a node not in chance and can be placed
f[i|(1<<hdk)][hdk+2]=min(f[i|(1<<hdk)][hdk+2],f[i][j+2]+dis[j+2][hdk+2]);
} //then do the change. why it's +2 is because I store 3 in position 1.(1 and 2 is no need)
}
}
}
}
for(int i=2;i<=k+1;++i){
ans=min(ans,f[(1<<k)-1][i]+dis[i][n]);
}
cout<<ans;
}
洛谷数据需要滚动数组优化,正在写.
[TK] Tourist Attractions的更多相关文章
- csp-s模拟48,49 Tourist Attractions,养花,画作题解
题面:https://www.cnblogs.com/Juve/articles/11569010.html Tourist Attractions: 暴力当然是dfs四层 优化一下,固定两个点,答案 ...
- LYDSY模拟赛day1 Tourist Attractions
/* 假设路径是 a − b − c − d,考虑枚举中间这条边 b − c,计 算有多少可行的 a 和 d. 设 degx 表示点 x 的度数,那么边 b − c 对答案的贡献为 (degb − 1 ...
- 解题:POI 2007 Tourist Attractions
题面 事实上这份代码在洛谷过不去,因为好像要用到一些压缩空间的技巧,我并不想(hui)写(捂脸) 先预处理$1$到$k+1$这些点之间相互的最短路和它们到终点的最短路,并记录下每个点能够转移到时的状态 ...
- [POI2007]Tourist Attractions
题目大意: 给你一个$n(n\leq 2\times 10^4)$个点,$m(m\leq 2\times 10^5)$条边的带边权的连通图.其中有$k(k\leq 20)$个关键点.关键点之间有$g$ ...
- 【JZOJ4857】Tourist Attractions(Bitset)
题意:给定一个n个点的无向图,求这个图中有多少条长度为4的简单路径. n<=1500 思路: #include<map> #include<set> #include&l ...
- [CSP-S模拟测试]:Tourist Attractions(简单图论+bitset)
题目描述 在美丽的比特镇一共有$n$个景区,编号依次为$1$到$n$,它们之间通过若干条双向道路连接.$Byteasar$慕名来到了比特镇旅游,不过由于昂贵的门票费,他只能负担起$4$个景区的门票费. ...
- 比特镇旅游(Tourist Attractions)【暴力+Bitset 附Bitset用法】
Online Judge:NOIP2016十连测第一场 T2 Label:暴力,Bitset 题目描述 在美丽的比特镇一共有n个景区,编号依次为1到n,它们之间通过若干条双向道路连接. Byteasa ...
- D. 旅游景点 Tourist Attractions 状压DP
题目描述 FGD想从成都去上海旅游.在旅途中他希望经过一些城市并在那里欣赏风景,品尝风味小吃或者做其他的有趣的事情.经过这些城市的顺序不是完全随意的,比如说FGD 不希望在刚吃过一顿大餐之后立刻去下一 ...
- 旅游景点 Tourist Attractions 题解
题面在这里 再次破了纪录,连做了3天... 让我们从头来一点一点分析 1.预处理 先看题面,乍一看貌似是个图论题,有n个点m条边,给定一些必须经过的点和强制经过顺序,求一条最短路 我们发现n和m都比较 ...
- noip2016十连测round1
A:String Master 题目:所谓最长公共子串,比如串 A:"abcde",串 B:"jcdkl",则它们的最长公共子串为串 "cd" ...
随机推荐
- 洛谷P1029 [NOIP2001 普及组] 最大公约数和最小公倍数问题
[NOIP2001 普及组] 最大公约数和最小公倍数问题 题目描述 洛谷题目链接:https://www.luogu.com.cn/problem/P1029 输入两个正整数 x, y,求出满足下列条 ...
- nacos:关于注册服务与配置管理
为什么要用nacos做配置中心? 1.nacos可以做到统一管理,而且在修改时可以做到动态管理,无需重启即可生效. 2.nacos通过namespace进行环境隔离, 约定: namespace:用于 ...
- 结合拦截器描述mybatis启动流程
简介 mybatis的启动入口一般有两个,在结合spring框架后由spring整合包下的SqlSessionFactoryBean启动 如果没有整合spring,则有XMLConfigBuilder ...
- 13、SpringMVC之异常解析器
13.1.环境搭建 创建名为spring_mvc_exception的新module,过程参考9.1节和9.5节 13.1.1.创建错误提示页 <!DOCTYPE html> <ht ...
- 网友开放的开源项目:网页版的A*算法可视化演示程序
相关项目: https://xueqiaoxu.me/#projects 项目介绍: A JavaScript path-finding library for grid based games. I ...
- 【转载】 你真的理解Python中MRO算法吗?
来自:www.xymlife.com 作者: XYM 链接:http://www.xymlife.com/2016/05/22/python_mro/ (点击阅读原文前往) ------------- ...
- 强化学习:reward function shaping —— 着陆器(lander)游戏中的奖励函数的设计
lander 游戏是强化学习问题中常使用的一个游戏场景,不同人对该问题都设置了不同的reward function,一直也没有对该游戏的各种reward function的设计做一个记录,正好看视频看 ...
- iOS开发基础148-ABM vs MDM
Apple Business Manager (ABM) vs. Mobile Device Management (MDM) Apple Business Manager (ABM) 优点: 集中管 ...
- 新晋 Committer!来自复旦大学的帅哥一枚
点亮Star️ · 支持我们 https://github.com/apache/dolphinscheduler 最近,社区星力量又迎来一位新晋 Committer,这次是来自复旦大学研究生在读的王 ...
- PHP转Go系列 | ThinkPHP与Gin框架之打造基于WebSocket技术的消息推送中心
大家好,我是码农先森. 在早些年前客户端想要实时获取到最新消息,都是使用定时长轮询的方式,不断的从服务器上获取数据,这种粗暴的骚操作实属不雅.不过现如今我也还见有人还在一些场景下使用,比如在 PC 端 ...