题解:

$k<=20,$ 考虑状压dp.
从 $1$ 号点走到 $n$ 号点经过的点的个数可能会非常多,但是强制要求经过的点一共才 $20$ 个.
而我们发现这个题好就好在可以经过某个城市,而不停留.
故我们在关键点之间进行转移的时候可以直接走最短路,而不用管别的.
令方程 $f[i][j]$ 表示访问过的关键点集合为 $i,$ 当前在点 $i$ 的最短路径.
考虑转移:
枚举下一个可以到达的关键节点 $k,$ 能转移到 $k$ 的条件是 $i$ 中有 $k$ 需要提前访问的元素,这个可以提前预处理.
如果成功转移,则方程为 $f[i|(1<<k)][i]+d[j][k],$ 其中 $d[j][k]$ 表示 $j$ 到 $k$ 的最短路.
由于 $j$ 只可能取到 $[1,20],$ 所以只需暴力跑 $20$ 遍最短路即可.

我不会说我还没调过样例~

以后有时间的话再调吧~

Code:

#include <bits/stdc++.h>
#define N 20003
#define ll long long
#define inf 1000000000
#define M (1<<21)
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
ll d[30][N],f[M][22];
int n,m,K,edges;
int done[N],hd[N],to[N<<1],nex[N<<1],val[N<<1],Log[22],phase[22];
int count(int c)
{
int l=0;
for(;c;c>>=1) if(c&1) ++l;
return l;
}
void getmin(ll &a,ll b)
{
if(b<a) a=b;
}
void addedge(int u,int v,int c)
{
nex[++edges]=hd[u],hd[u]=edges,to[edges]=v,val[edges]=c;
}
struct Node
{
int u;
ll dis;
Node(int u=0,ll dis=0):u(u),dis(dis){}
bool operator<(Node b)const
{
return b.dis<dis;
}
};
priority_queue<Node>q;
void Dijkstra(int s)
{
int i,v,u;
for(i=0;i<=n;++i) d[s][i]=inf,done[i]=0;
for(d[s][s]=0,q.push(Node(s,0));!q.empty();)
{
Node e=q.top(); q.pop();
u=e.u;
if(done[u]) continue;
done[u]=1;
for(i=hd[u];i;i=nex[i])
{
v=to[i];
if(d[s][v]>d[s][u]+val[i])
{
d[s][v]=d[s][u]+val[i];
q.push(Node(v,d[s][v]));
}
}
}
}
int main()
{
int i,j;
setIO("input");
scanf("%d%d%d",&n,&m,&K);
for(i=0;i<=20;++i) Log[i]=(1<<i);
for(i=1;i<=m;++i)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c),addedge(a,b,c),addedge(b,a,c);
}
for(i=1;i<=K+1;++i) Dijkstra(i);
if(!K)
{
printf("%lld\n",d[1][n]);
return 0;
}
int Q;
scanf("%d",&Q);
for(i=1;i<=Q;++i)
{
int a,b;
scanf("%d%d",&a,&b);
if(a!=1) phase[b]+=Log[a-2];
}
memset(f,0x3f,sizeof(f));
for(int sta=1;sta<Log[K];++sta)
{
if(count(sta)==1)
{
for(j=2;j<=K+1;++j)
{
if(Log[j-2]&sta)
{
f[sta][j-2]=d[1][j];
printf("%d %lld\n",j,f[sta][j-2]);
break;
}
}
}
for(j=2;j<=K+1;++j)
{
if(Log[j-2]&sta)
{
for(int cc=2;cc<=K+1;++cc)
{
if( !(Log[cc-2]&sta) && ((sta & phase[cc]) == phase[cc]) )
getmin(f[sta|Log[cc-2]][cc-2],f[sta][j-2]+d[j][cc]);
}
}
}
}
ll ans=10000000000;
for(i=2;i<=K+1;++i)
{
getmin(ans, f[Log[K]-1][i-2]+d[i][n]);
}
printf("%lld\n",ans);
return 0;
}

  

BZOJ 1097: [POI2007]旅游景点atr 状态压缩+Dijkstra的更多相关文章

  1. BZOJ 1097: [POI2007]旅游景点atr( 最短路 + 状压dp )

    先最短路预处理, 然后状压就行了 -------------------------------------------------------------------------- #include ...

  2. bzoj [POI2007]旅游景点atr 状态压缩+Dij

    [POI2007]旅游景点atr Time Limit: 30 Sec  Memory Limit: 357 MBSubmit: 2258  Solved: 595[Submit][Status][D ...

  3. bzoj 1097 [POI2007]旅游景点atr(最短路,状压DP)

    [题意] 给定一个n点m边的无向图,要求1开始n结束而且顺序经过k个点,给出经过关系x,y代表y必须在x之后经过,求最短路. [思路] 先对k个点进行spfa求出最短路. 设f[s][i]代表经过点集 ...

  4. BZOJ 1097: [POI2007]旅游景点atr [DP 状压 最短路]

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

  5. 【BZOJ】1097: [POI2007]旅游景点atr(spfa+状压dp)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1097 首先还是我很sb....想到了分层图想不到怎么串起来,,,以为用拓扑序搞转移,,后来感到不行. ...

  6. BZOJ1097: [POI2007]旅游景点atr

    ..k次最短路后,考虑如何满足先走一些点 用状压dp,每一个点考虑它所需要经过的点a[i],当当前走过的点包含a[i]时,i 这个点才可以到达. 写的时候用记忆化搜索. #include<bit ...

  7. 【BZOJ1097】[POI2007]旅游景点atr 最短路+状压DP

    [BZOJ1097][POI2007]旅游景点atr Description FGD想从成都去上海旅游.在旅途中他希望经过一些城市并在那里欣赏风景,品尝风味小吃或者做其他的有趣的事情.经过这些城市的顺 ...

  8. [POI2007]旅游景点atr BZOJ1097

    分析: 我们可以考虑,因为我们必须经过这些节点,那么我们可以将它状压,并且我们因为可以重复走,只是要求停顿前后,不要求遍历前后,那么我们之间存一下点与点之间的最短路,之后每次转移一下就可以了. f[i ...

  9. 【bzoj1097】[POI2007]旅游景点atr 状压dp+堆优化Dijkstra

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

随机推荐

  1. Kubernetes组件-CronJob(定时任务)

    ⒈简介: Kubernetes的Job资源在创建时会立即运行pod.但是许多批处理任务需要在特定的时间运行,或者在指定的时间间隔内重复运行.在Linux和类UNIX操作系统中,这些任务通常被称为cro ...

  2. (三)IDEA创建Spring项目

    新建项目的时候,选择Spring : 在Spring的下面,有许多选项,根据自己需求选择,我是初学,就一个都没有勾选: 选择 Web Application 选项 默认是下载Spring的jar包:如 ...

  3. Kernel--试题

    1. 内核堆栈区别: 1.栈自动分配回收,函数里面声明的变量:2.堆:malloc kmalloc申请的空间,需要自己释放 https://blog.csdn.net/tainjau/article/ ...

  4. 织梦DedeCMS给栏目添加缩略图调用的方法

    织梦DedeCMS的栏目调用仅仅只有文字调用,没有栏目缩略图调用,而我们有时候又需要给栏目添加缩略图,并能够在前台调用,就可以试试通过下面的方法,给栏目添加缩略图. 首先要给栏目数据库表添加一个存储缩 ...

  5. celery(芹菜) 异步任务 定时任务 周期任务

    什么是celery Celery是一个简单.灵活且可靠的,处理大量消息的分布式系统 专注于实时处理的异步任务队列 同时也支持任务调度 celery架构 celery的架构由三部分组成,消息中间件(me ...

  6. 标准库中最值得关注的两个 装饰器是 lru_cache 和全新的 singledispatch(Python 3.4 新增)

    clock 装饰器 def clock(func): @functools.wraps(func) def clocked(*args, **kwargs): t0 = time.perf_count ...

  7. 3-MySQL DBA笔记-开发基础

    第二部分 开发篇 本篇首先讲述数据库开发的一些基础知识,如关系数据模型.常用的SQL语法.范式.索引.事务等,然后介绍编程开发将会涉及的数据库的一些技巧,最后结合生产实际,提供一份开发规范供大家参考. ...

  8. oracle中查询表中的触发器,关闭启用操作

    1.查询指定表中有哪些触发器 select * from all_triggers WHERE table_name='表名' 2.禁用指定表中所有的触发器 alter table table_nam ...

  9. Dubbo 配置参数

    关闭启动检查 在dubbo多模块项目启动的时候为了并行启动多个服务,缩短启动时间,需要解除模块之间的依赖检测 dubbo.consumer.check=false @Reference(check = ...

  10. adb实操

    一.命令 adb connect IP:5555 adb disconnect IP:5555 adb remount adb install 安装包的绝对路径 二.获取logcat信息 1.制作文件 ...