题意:

Description

  终于放寒假了,小明要和女朋友一起去看电影。这天,女朋友想给小明一个考验,在小明正准备出发的时候,女朋友告诉他,她在电影院等他,小明过来的路线必须满足给定的规则: 
  1、假设小明在的位置是1号点,女朋友在的位置是n号点,则他们之间有n-2个点可以走,小明每次走的时候只能走到比当前所在点编号大的位置; 
  2、小明来的时候不能按一定的顺序经过某些地方。比如,如果女朋友告诉小明不能经过1 -> 2 -> 3,那么就要求小明来的时候走过的路径不能包含有1 -> 2 -> 3这部分,但是1 -> 3 或者1 -> 2都是可以的,这样的限制路径可能有多条。 
  这让小明非常头痛,现在他把问题交给了你。 
  特别说明,如果1 2 3这三个点共线,但是小明是直接从1到3然后再从3继续,那么此种情况是不认为小明经过了2这个点的。 
  现在,小明即想走最短的路尽快见到女朋友,又不想打破女朋友的规定,你能帮助小明解决这个问题吗?

Input

  输入包含多组样例,每组样例首先包含两个整数n和m,其中n代表有n个点,小明在1号点,女朋友在n号点,m代表小明的女朋友有m个要求; 
  接下来n行每行输入2个整数x 和y(x和y均在int范围),代表这n个点的位置(点的编号从1到n); 
  再接着是m个要求,每个要求2行,首先一行是一个k,表示这个要求和k个点有关,然后是顺序给出的k个点编号,代表小明不能走k1 -> k2 -> k3 ……-> ki这个顺序的路径; 
  n 和 m等于0的时候输入结束。

   [Technical Specification] 
  2 <= n <= 50 
  1 <= m <= 100 
  2 <= k <= 5 

Output

  对于每个样例,如果存在满足要求的最短路径,请输出这个最短路径,结果保留两位小数;否则,请输出”Can not be reached!” (引号不用输出)。
 
 #include <bits/stdc++.h>
#include <cstdio>
#include <iostream>
#include <algorithm>
#define ll long long
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define st first
#define nd second
#define mp make_pair
#define pii pair<int, int>
#define pdi pair<double, int>
#define gg puts("gg");
//#define local
//#define out1
using namespace std;
const int N = 6e4+;
const int inf = 0x3f3f3f3f;
int id(int c){
return c-;
}
struct Tire{
int nex[N][], fail[N],end[N], ch[N];
int root, L, tot;
int newnode(){
memset(nex[L], -, sizeof(nex[L]));
end[L] = ;
ch[L] = ;
return L++;
}
void init(){
L = tot = ;
root = newnode();
}
void insert(int* s, int len, int tag){
int now = root;
for(int i = ; i < len; i++){
int p = id(s[i]);
if(nex[now][p] == -)
nex[now][p] = newnode();
now = nex[now][p];
ch[now] = p;
}
end[now] = tag;
}
void build(){
queue<int> Q;
fail[root] = root;
for(int i = ; i < ; i++){
int& u = nex[root][i];
if(u == -)
u = root;
else{
fail[u] = root;
Q.push(u);
}
}
while(!Q.empty()){
int now = Q.front();
Q.pop();
for(int i = ; i < ; i++){
int& u = nex[now][i];
if(u == -)
u = nex[ fail[now] ][i];
else{
fail[u] = nex[ fail[now] ][i];
end[u] |= end[ fail[u] ];
Q.push(u);
}
}
}
}
};
Tire ac;
ll x[], y[];
double w[][];
int s[];
vector< pdi > ve[];
priority_queue< pdi, vector< pdi >, greater< pdi > >Q;
double d[];
double dijkstra(int S){
int i, x;
for(i = ; i < ; i++) d[i] = 1e30;
Q.push(mp(d[S]=,S));
while(!Q.empty()){
pdi t = Q.top(); Q.pop();
if(d[x = t.nd] < t.st) continue;
for(i = ; i < ve[x].size(); i++)
if(d[x]+ve[x][i].st < d[ve[x][i].nd]){
d[ve[x][i].nd] = d[x]+ve[x][i].st;
Q.push( mp(d[ve[x][i].nd], ve[x][i].nd) );
}
}
}
int main(){
int n, m, ca = ;
while(~scanf("%d%d", &n, &m), n+m){
for(int i = ; i <= n; i++)
scanf("%lld%lld", x+i, y+i);
for(int i = ; i <= n; i++)
for(int j = ; j <= n; j++) w[i][j] = 1e30;
for(int i = ; i <= n; i++)
for(int j = i+; j <= n; j++)
w[i][j] = sqrt( 1.0*(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]) ); ac.init();
for(int i = ; i <= n; i++){
s[] = i;
ac.insert(s, , );
} for(int i = ; i <= m; i++){
int k; scanf("%d", &k);
for(int j = ; j < k; j++)
scanf("%d", s+j);
ac.insert(s, k, );
}
ac.build();
for(int i = ; i < ac.L; i++) ve[i].clear();
for(int i = ; i < ac.L; i++){
int u = ac.ch[i]+;
for(int j = u+; j <= n; j++) {
int to = ac.nex[i][id(j)];
if(!ac.end[to]) ve[i].push_back( mp(w[u][j], to) );
}
} dijkstra(ac.nex[][id()]);
double ans = 1e30;
for(int i = ; i < ac.L; i++){
if(ac.ch[i] == id(n))
ans = min(ans, d[i]);
}
if(ans < 1e25)
printf("%.2f\n", ans);
else
puts("Can not be reached!");
}
return ;
}

后记:发现debug能力实在太弱了...调半天没看出来哪错了...代码能力不够啊!!!

HDU4511 AC自动机+dijkstra的更多相关文章

  1. HDU4511 小明系列故事——女友的考验 —— AC自动机 + DP

    题目链接:https://vjudge.net/problem/HDU-4511 小明系列故事——女友的考验 Time Limit: 500/200 MS (Java/Others)    Memor ...

  2. HDU4511 小明系列故事——女友的考验(AC自动机 + DP)

    题目大概说有平面有n个点,从1点出发走到n点,每一步只能走到序号比当前更大的点且走的序列不能包含给定的m个序列中的任何一个,问1走到n的最短路. 用m个序列建个AC自动机,后缀包含整个序列的结点标记一 ...

  3. [C#] 逆袭——自制日刷千题的AC自动机攻克HDU OJ

    前言 做过杭电.浙大或是北大等ACM题库的人一定对“刷题”不陌生,以杭电OJ为例:首先打开首页(http://acm.hdu.edu.cn/),然后登陆,接着找到“Online Exercise”下的 ...

  4. AC自动机小结

    专题链接 第一题--hdu2222 Keywords Search ac自动机的模板题,入门题.  题解 第二题--hdu2896 病毒侵袭   一类病毒的入门题,类似模板  题解 第三题--hdu3 ...

  5. HDU 4511 小明系列故事——女友的考验 (AC自动机+DP)

    小明系列故事——女友的考验 Time Limit: 500/200 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total ...

  6. 基于trie树做一个ac自动机

    基于trie树做一个ac自动机 #!/usr/bin/python # -*- coding: utf-8 -*- class Node: def __init__(self): self.value ...

  7. AC自动机-算法详解

    What's Aho-Corasick automaton? 一种多模式串匹配算法,该算法在1975年产生于贝尔实验室,是著名的多模式匹配算法之一. 简单的说,KMP用来在一篇文章中匹配一个模式串:但 ...

  8. python爬虫学习(11) —— 也写个AC自动机

    0. 写在前面 本文记录了一个AC自动机的诞生! 之前看过有人用C++写过AC自动机,也有用C#写的,还有一个用nodejs写的.. C# 逆袭--自制日刷千题的AC自动机攻克HDU OJ HDU 自 ...

  9. BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]

    2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2545  Solved: 1419[Submit][Sta ...

随机推荐

  1. Java-马士兵设计模式学习笔记-代理模式-动态代理 调用Proxy.newProxyInstance()

    一.概述 1.目标:不自己写代理类,利用Proxy.newProxyInstance()动态生成 2.用到的知识点: (1)//编译源码,生成class,注意编译环境要换成jdk才有compiler, ...

  2. Android高级第十一讲之不同系统间的区别

    本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! Android系统不断的升级,从基础到中级再到高级,逐步升级是软件工程敏捷开发的一个重点,在每个版本 ...

  3. Nodejs开发(2.连接MongoDB)

    一.先配置MongoDB Win10下下载那个安装版,zip版的会报却各种DLL,安装在你希望的路径,实在安装错了,就剪切过来也行(本例E:\mongodb). 然后是配置启动脚本,就是写一个bat文 ...

  4. CSS之border

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. NULLIF()函数使用讲解

    NULLIF()函数接受两个参数.如果它们相等,那么返回空值:否则,返回第一个参数. 等价于下面的表达式: case when expression1=expression2 then null el ...

  6. CTeX学习心得总结

    CTeX 又称 CTeX中文套装,是基于 Windows 下的 MiKTeX 的发行版,集成了编辑器WinEdt 和 PostScript 处理软件 Ghostscript 和 GSview 等主要工 ...

  7. 解决SVN不显示状态图标

    打开注册表,找到"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlay ...

  8. Groovy学习笔记(二)

    在上一篇文章中我们主要学习了如何搭建Groovy开发环境,为我们的Groovy之旅做好了准备工作,不知道你是否准备好了?接下来我们就一起看看Groovy与我们熟悉的Java有什么异同. Groovy是 ...

  9. 使用plsql执行计划进行sql调优(转载)

    一段SQL代码写好以后,可以通过查看SQL的执行计划,初步预测该SQL在运行时的性能好坏,尤其是在发现某个SQL语句的效率较差时,我们可以通过查看执行计划,分析出该SQL代码的问题所在. 那么,作为开 ...

  10. PHP二维数组提取函数----把不需要的数据剔除

    首先说明一些这个函数的应用场景,比如说你得到的数据是个二维数组,里面的很多成员其实是不必要的,比如说api调用后不必要给别人返回一些用不到的垃圾数据吧,如下是代码. <?php /* * del ...