传送门

题意:

一个无向图,从$1$到$n$,要求必须经过$2,3,...,k+1$,给出一些限制关系,要求在经过$v \le k+1$之前必须经过$u \le k+1$

求最短路


预处理出$1...k+1$到其他点的最短路

然后$f[i][s]$表示当前在$i$已经经过的点的集合为$s$的最短路

只考虑$1,2,...,k+1$就行了,

注意$1$也要考虑,一个点可能经过多次

然后实测dij比spfa快....我想试$pb\_ds$来着结果发现我的电脑上没有ext/pb_ds/priority_queue.hpp

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=2e4+,M=2e5+,K=,S=(<<)+,INF=1e9;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n,m,k,u,v,w;
int need[K],f[K][S];
int d[K][N];
struct Edge{
int v,w,ne;
}e[M<<];
int cnt,h[N];
inline void ins(int u,int v,int w){
cnt++;
e[cnt].v=v;e[cnt].w=w;e[cnt].ne=h[u];h[u]=cnt;
cnt++;
e[cnt].v=u;e[cnt].w=w;e[cnt].ne=h[v];h[v]=cnt;
}
int q[N],head,tail,inq[N];
inline void lop(int &x){if(x==N) x=;else if(x==) x=N-;}
void spfa(int s,int *d){
head=tail=;
d[s]=;inq[s]=;
q[tail++]=s;
while(head!=tail){
int u=q[head++];inq[u]=;lop(head);
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v;
if(d[v]>d[u]+e[i].w){
d[v]=d[u]+e[i].w;
if(!inq[v]){
inq[v]=;
if(d[v]<d[q[head]]) head--,lop(head),q[head]=v;
else q[tail++]=v,lop(tail);
}
}
}
}
}
int main(){
freopen("in","r",stdin);
n=read();m=read();k=read();
for(int i=;i<=m;i++) u=read(),v=read(),w=read(),ins(u,v,w);
memset(d,,sizeof(d));
for(int i=;i<=k+;i++) spfa(i,d[i]);
int c=read();
while(c--) u=read()-,v=read(),need[v]|=(<<u); memset(f,-,sizeof(f));
int All=<<k;
f[][]=;
for(int s=;s<All;s++)
for(int i=;i<=k+;i++) if(f[i][s]!=-){
for(int j=;j<=k+;j++) if(j!=i && (need[j]&s)==need[j] ){
int t=s|(<<(j-));
if(f[j][t]>f[i][s]+d[i][j] || f[j][t]==-)
f[j][t]=f[i][s]+d[i][j];
}
}
int ans=INF;
for(int i=;i<=k+;i++)
if(f[i][All-]!=-) ans=min(ans,f[i][All-]+d[i][n]);
printf("%d",ans);
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
#define pii pair<int,int>
#define MP make_pair
#define fir first
#define sec second
typedef long long ll;
const int N=2e4+,M=2e5+,K=,S=(<<)+,INF=1e9;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n,m,k,u,v,w;
int need[K],f[K][S];
int d[K][N];
struct Edge{
int v,w,ne;
}e[M<<];
int cnt,h[N];
inline void ins(int u,int v,int w){
cnt++;
e[cnt].v=v;e[cnt].w=w;e[cnt].ne=h[u];h[u]=cnt;
cnt++;
e[cnt].v=u;e[cnt].w=w;e[cnt].ne=h[v];h[v]=cnt;
} priority_queue<pii,vector<pii>,greater<pii> > q;
bool done[N];
void dij(int s,int *d){
for(int i=;i<=n;i++) d[i]=INF,done[i]=;
d[s]=;
q.push(MP(d[s],s));
while(!q.empty()){
int u=q.top().sec;q.pop();
if(done[u]) continue;done[u]=;
for(int i=h[u];i;i=e[i].ne)
if(d[e[i].v]>d[u]+e[i].w){
d[e[i].v]=d[u]+e[i].w;
q.push(MP(d[e[i].v],e[i].v));
}
}
}
int main(){
freopen("in","r",stdin);
n=read();m=read();k=read();
for(int i=;i<=m;i++) u=read(),v=read(),w=read(),ins(u,v,w);
memset(d,,sizeof(d));
for(int i=;i<=k+;i++) dij(i,d[i]);
int c=read();
while(c--) u=read()-,v=read(),need[v]|=(<<u); memset(f,-,sizeof(f));
int All=<<k;
f[][]=;
for(int s=;s<All;s++)
for(int i=;i<=k+;i++) if(f[i][s]!=-){
for(int j=;j<=k+;j++) if(j!=i && (need[j]&s)==need[j] ){
int t=s|(<<(j-));
if(f[j][t]>f[i][s]+d[i][j] || f[j][t]==-)
f[j][t]=f[i][s]+d[i][j];
}
}
int ans=INF;
for(int i=;i<=k+;i++)
if(f[i][All-]!=-) ans=min(ans,f[i][All-]+d[i][n]);
printf("%d",ans);
}

BZOJ 1097: [POI2007]旅游景点atr [DP 状压 最短路]的更多相关文章

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

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

  2. BZOJ 1097: [POI2007]旅游景点atr 状态压缩+Dijkstra

    题解: $k<=20,$ 考虑状压dp. 从 $1$ 号点走到 $n$ 号点经过的点的个数可能会非常多,但是强制要求经过的点一共才 $20$ 个. 而我们发现这个题好就好在可以经过某个城市,而不 ...

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

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

  4. 【BZOJ-1097】旅游景点atr SPFA + 状压DP

    1097: [POI2007]旅游景点atr Time Limit: 30 Sec  Memory Limit: 357 MBSubmit: 1531  Solved: 352[Submit][Sta ...

  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. bzoj [POI2007]旅游景点atr 状态压缩+Dij

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

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

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

随机推荐

  1. Java集合系列[4]----LinkedHashMap源码分析

    这篇文章我们开始分析LinkedHashMap的源码,LinkedHashMap继承了HashMap,也就是说LinkedHashMap是在HashMap的基础上扩展而来的,因此在看LinkedHas ...

  2. [学习OpenCV攻略][006][平滑图片]

    cvCreateImage(图片大小,像素位数,通道数) 创建图片,根据输入的图片大小,各个通道像素点的位数,和通道数.像素点宏IPL_DEPTH_8U cvGetSize(图片) 得到图片的大小信息 ...

  3. JavaScript八张思维导图—编程实践

    JS基本概念 JS操作符 JS基本语句 JS数组用法 Date用法 JS字符串用法 JS编程风格 JS编程实践 不知不觉做前端已经五年多了,无论是从最初的jQuery还是现在火热的Angular,Vu ...

  4. ZooKeeper 分布式共享锁的实现

    原创播客,如需转载请注明出处.原文地址:http://www.cnblogs.com/crawl/p/8352919.html ------------------------------------ ...

  5. css中,如何设置前景色的透明度?

    谢谢 我等待的他 | 浏览 255446 次 推荐于2016-01-13 12:27:03 最佳答案 css控制透明度倒不麻烦. filter:alpha(opacity=50); -moz-opac ...

  6. Python3 的序列

    序列 1.根据列表.元组.字符串的共同点把它们统称为序列(他们都是兄弟呀) 1)都可以通过索引来的到每一个元素 2)默认索引值都是从零开始(Python也支持负数索引) 3)都可以通过分片(切片)的方 ...

  7. springMVC controller配置方式总结

    第一种:不配置controller 的bean.(注解的方式) 在dispatch-servlet.xml中,在beans节点下配置context:component-scan节点 <!-- 启 ...

  8. Freemarker 入门示例

    初步学习freemarker ,先做一个简单的HelloWord程序! 新建一个WEB工程,下载(我使用的是freemarker-2.3.20)freemarker并导入freemarker.jar, ...

  9. 数据结构 链式哈希表(Hash Table)的接口定义与实现分析(完整代码)

    链式哈希表的接口定义 关于哈希表与链式哈希表的描述可以参阅:http://www.cnblogs.com/idreamo/p/7990860.html 链式哈希表的操作与属性有:初始化.销毁.插入元素 ...

  10. SSH key introduction

    Preface At the first time, we take the connection with GitLab remote server. You need to type userna ...