Description

FGD想从成都去上海旅游。在旅途中他希望经过一些城市并在那里欣赏风景,品尝风味小吃或者做其他的有趣的事情。经过这些城市的顺序不是完全随意的,比如说FGD不希望在刚吃过一顿大餐之后立刻去下一个城市登山,而是希望去另外什么地方喝下午茶。幸运的是,FGD的旅程不是既定的,他可以在某些旅行方案之间进行选择。由于FGD非常讨厌乘车的颠簸,他希望在满足他的要求的情况下,旅行的距离尽量短,这样他就有足够的精力来欣赏风景或者是泡MM了_.整个城市交通网络包含N个城市以及城市与城市之间的双向道路M条。城市自1至N依次编号,道路亦然。没有从某个城市直接到它自己的道路,两个城市之间最多只有一条道路直接相连,但可以有多条连接两个城市的路径。任意两条道路如果相遇,则相遇点也必然是这N个城市之一,在中途,由于修建了立交桥和下穿隧道,道路是不会相交的。每条道路都有一个固定长度。在中途,FGD想要经过K(K<=N-2)个城市。成都编号为1,上海编号为N,而FGD想要经过的N个城市编号依次为2,3,…,K+1.举例来说,假设交通网络如下图。FGD想要经过城市2,3,4,5,并且在2停留的时候在3之前,而在4,5停留的时候在3之后。那么最短的旅行方案是1-2-4-3-4-5-8,总长度为19。注意FGD为了从城市2到城市4可以路过城市3,但不在城市3停留。这样就不违反FGD的要求了。并且由于FGD想要走最短的路径,因此这个方案正是FGD需要的。

Input

第一行包含3个整数N(2<=N<=20000),M(1<=M<=200000),K(0<=K<=20),意义如上所述。

之后有q条限制,每次给一对\(x_i,y_i\),代表\(x_i\)要在\(y_i\)之前休息过

Output

只包含一行,包含一个整数,表示最短的旅行距离。

Sample Input

8 15 4

1 2 3

1 3 4

1 4 4

1 6 2

1 7 3

2 3 6

2 4 2

2 5 2

3 4 3

3 6 3

3 8 6

4 5 2

4 8 6

5 7 4

5 8 6

3

2 3

3 4

3 5

Sample Output

19

HINT



上图为题中所给出的例子


这题我不想说什么,题目输入描述都不讲清楚……看到k<=20,这不直接上状压吗

把1~k+1这些点之间的距离去全部处理出来,然后对于每个点记上一个限制,就可以愉快地用状压DP了

有K=0的情况,被坑了

/*program from Wolfycz*/
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
inline int read(){
int x=0,f=1;char ch=getchar();
for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+ch-'0';
return x*f;
}
inline void write(int x){
if (x>=10) write(x/10);
putchar(x%10+'0');
}
const int N=2e4,M=2e5,K=20;
int pre[(M<<1)+10],now[N+10],child[(M<<1)+10],val[(M<<1)+10];
int h[N+10],deep[N+10];
bool vis[N+10];
int dis[K+5][K+5],f[21][1<<K],v[K+5];
int n,m,k,tot,Ans=inf;
void join(int x,int y,int z){pre[++tot]=now[x],now[x]=tot,child[tot]=y,val[tot]=z;}
void SPFA(int x){//预处理,dijkstra会快一些,但是我懒
memset(vis,0,sizeof(vis));
memset(deep,63,sizeof(deep));
int head=0,tail=1;
h[1]=x,vis[x]=1,deep[x]=0;
while (head!=tail){
if (++head>N) head=1;
int Now=h[head];
for (int p=now[Now],son=child[p];p;p=pre[p],son=child[p]){
if (deep[son]>deep[Now]+val[p]){
deep[son]=deep[Now]+val[p];
if (!vis[son]){
if (++tail>N) tail=1;
vis[h[tail]=son]=1;
}
}
}
vis[Now]=0;
}
for (int i=1;i<=k+1;i++) dis[x][i]=deep[i];
dis[x][0]=deep[n];
}
void dp(){
memset(f,63,sizeof(f));
for (int i=1;i<=k;i++) if (!v[i]) f[i][1<<(i-1)]=dis[1][i+1];
for (int sta=1;sta<1<<k;sta++){
for (int i=1;i<=k;i++){
if ((f[i][sta]==inf)||(!(sta&(1<<(i-1))))) continue;
for (int j=1;j<=k;j++){
if (((v[j]&sta)==v[j])&&(!(sta&(1<<(j-1))))){
f[j][sta|(1<<(j-1))]=min(f[j][sta|(1<<(j-1))],f[i][sta]+dis[i+1][j+1]);
}
}
}
}
}
int main(){
n=read(),m=read(),k=read();
for (int i=1;i<=m;i++){
int x=read(),y=read(),z=read();
join(x,y,z),join(y,x,z);
}
if (!k){SPFA(1);printf("%d\n",deep[n]);return 0;}//特判
for (int i=1;i<=k+1;i++) SPFA(i);
int q=read();
for (int i=1;i<=q;i++){//由于他要经过的点是2~k+1,所以处理起来会有点小恶心
int x=read(),y=read();
v[y-1]|=1<<(x-2);
}
dp();
for (int i=1;i<=k;i++) Ans=min(Ans,f[i][(1<<k)-1]+dis[i+1][0]);
printf("%d\n",Ans);
}

[POI2007]旅游景点atr的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  9. 2018.11.06 bzoj1097: [POI2007]旅游景点atr(最短路+状压dp)

    传送门 预处理出不能在每个点停留之后才停留的点的状态. 对kkk个点都跑一次最短路存下来之后只需要简单状压一下就能过了吐槽原题空间64MB蒟蒻无能为力 然后用fillfillfill赋极大值的时候当m ...

随机推荐

  1. 【转】面向切面编程-AOP,挺有用的

    原文:http://blog.csdn.net/yangzhihello/article/details/40377399 下面的代码有点问题, ins[methodName] = function( ...

  2. 非计算机专业的伟伯是怎样拿到阿里Offer的。求职励志!!!

    写在前面: 2015 年 7 月初.參加阿里巴巴校招内推, 8 月 15 日拿到研发project师 JAVA 的 offer .我的专业并不是计算机,也没有在互联网公司实习过,仅仅有一些学习和面试心 ...

  3. python 多线程中同步的小样例

    #!/usr/bin/python # -*- coding: UTF-8 -*- # 在一个资源池中.获取资源 # Author: zhang # Date: 2015-7-27 import ti ...

  4. HDU 1017 A Mathematical Curiosity【看懂题意+穷举法】

    //2014.10.17    01:19 //题意: //先输入一个数N,然后分块输入,每块输入每次2个数,n,m,直到n,m同一时候为零时  //结束,当a和b满足题目要求时那么这对a和b就是一组 ...

  5. fedora下安装xdot和objgraph

    前提:安装好了python 1.先下载xdot-0.6.tar.gz和objgraph-1.8.0-py27-none-any.whl,你也可以在官网上下载其他版本. 2.下载完后,解压. 3.打开终 ...

  6. 【转载】SOAP协议介绍

    SOAP是用在分散或分布的环境中交换信息的简单的协议,它是一个基于XML的协议,包括三个部分:封装定义了一个描述消息中包含什么内容以及如何处理它们的框架,编码规则用于表示应用程序定义的数据类型的实例, ...

  7. JavaScript-创建第一个自己的类库

    通过上一节面向对象和原型的学习. 我们知道了怎样创建一个类,包含类的私有化属性和方法.公有化属性和方法.静态属性和方法.在这里略微回想一下.首先要创建一个类能够通过1.new object().2.利 ...

  8. HDU OJ u Calculate e

    这是一道简单的数学计算问题   主义好输出格式就好 #include<stdio.h> int main() { printf("n e\n- -----------\n&quo ...

  9. 哨兵和docker容器

    1,redis哨兵的配置 redis-6379配置文件内容如下 cat redis-6379.conf port 6379 daemonize yes logfile "6379.log&q ...

  10. 超过经理收入的员工 表的自JOIN

    https://leetcode-cn.com/problems/employees-earning-more-than-their-managers/description/ The Employe ...