题目大意:

在欧几里得平面上给出n个点的坐标.你需要从1点走到n点取最短路.但是有m个限制条件:你的行走路径中不得含有m个路径片段 (类似a -> b -> c …).求最短路.

题目思路:

不难想到结合最短路.对m个片段建立AC自动机.将叶子节点标记为危险节点.Build的过程中传递危险节点.然后不含有m个路径片段本质上就是不经过Trie图上的这些危险节点.则容易想到状态:dp(i,j)dp(i,j)dp(i,j)代表在i号节点,且AC自动机上在j号节点上的最短路径.类似分层最短路.跑一跑即可.

注:这里的字符集大小为 n并且范围是 [1,n][1,n][1,n] 而不是 [0,n)[0,n)[0,n).千万注意这个细节…因为这个WA了半个小时…
AC代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 505;
namespace AC
{int tr[maxn][55] , End[maxn] , fail[maxn] , tot;int char_sz;void init(int sz){tot = 0;char_sz = sz;for (int i = 0 ; i < maxn ; i++){for (int j = 1 ; j <= 54 ; j++){tr[i][j] = 0;}fail[i] = End[i] = 0;}}void add (int s[] , int n){int u = 0;for (int i = 1 ; i <= n ; i++){if (!tr[u][s[i]]) tr[u][s[i]] = ++tot;u = tr[u][s[i]];}End[u] = true;}queue<int> q;void build (){while (q.size()) q.pop();for (int i = 1 ; i <= char_sz ; i++){if (tr[0][i]) q.push(tr[0][i]);}while (q.size()){int u = q.front();q.pop();for (int i = 1 ; i <= char_sz ; i++){if (tr[u][i]){fail[tr[u][i]] = tr[fail[u]][i];q.push(tr[u][i]);}else {tr[u][i] = tr[fail[u]][i];}}End[u] |= End[fail[u]];}}
}
int n , m;
struct No{double x , y;
}node[55];
double mp[55][55];
int s[15] , book[55][505];
double dp[55][505];
double getdist(int a , int b)
{return sqrt((node[a].x - node[b].x) * (node[a].x - node[b].x) + (node[a].y - node[b].y) * (node[a].y - node[b].y));
}
struct Node
{int id , u;double dis;Node (int idd , int uu , double dist){id = idd;u = uu;dis = dist;}bool operator < (const Node & a) const {return dis > a.dis;}
};
priority_queue <Node> Q;
void dijstra ()
{using namespace AC;for (int i = 0 ; i <= 50 ; i++)for (int j = 0 ; j <= 500 ; j++)dp[i][j] = -1;memset (book , 0 , sizeof book);if (End[tr[0][1]]) return ;dp[1][tr[0][1]] = 0;Q.push(Node(1 , tr[0][1] , 0));while (Q.size()){Node tmp = Q.top();Q.pop();int id = tmp.id , u = tmp.u;double dis = tmp.dis;if (book[id][u]) continue;book[id][u] = 1;for (int v = id + 1 ; v <= n ; v++){if (book[v][tr[u][v]]) continue;if (End[tr[u][v]]) continue;if (dp[v][tr[u][v]] < 0 || dp[v][tr[u][v]] > dis + mp[id][v]){dp[v][tr[u][v]] = dis + mp[id][v];Q.push(Node(v , tr[u][v] , dp[v][tr[u][v]]));}}}return ;
}
int main()
{while(scanf("%d%d" , &n , &m) , n || m){AC::init(n);for (int i = 1 ; i <= n ; i++){scanf("%lf%lf" , &node[i].x , &node[i].y);}for (int i = 1 ; i <= m ; i++){int k; scanf("%d" , &k);for (int j = 1 ; j <= k ; j++){scanf("%d" , s + j);}AC::add(s , k);}AC::build();for (int i = 1 ; i <= n ; i++)for (int j = 1 ; j <= n ; j++)mp[i][j] = getdist(i , j);dijstra();double ans = -1;bool ok = false;for (int i = 0; i <= AC::tot ; i++){if (dp[n][i] < 0) continue;ok = true;if (ans < 0 || ans > dp[n][i]) ans = dp[n][i];}if (ok)printf("%.2f\n" , ans);elseprintf("Can not be reached!\n");}return 0;
}

AC自动机专题:配合最短路问题-HDU5411相关推荐

  1. 转自kuangbin的AC自动机(赛前最后一博)

    有了KMP和Trie的基础,就可以学习神奇的AC自动机了.AC自动机其实就是在Trie树上实现KMP,可以完成多模式串的匹配.           AC自动机 其实 就是创建了一个状态的转移图,思想很 ...

  2. [专题总结]AC自动机

    其实前面的模板也不是1A,我在题库里提前做过,也不必在意罚时,刚开始我在做别的专题 裸模板我就不说了,各个博客讲解的很明白 1 void insert(string s){ 2 int p=0,len ...

  3. HihoCoder - 1877 Approximate Matching(AC自动机+dp)

    题目链接:点击查看 题目大意:给出一个长度为 n 的 01 字符串,规定近似相等的定义是,两个长度相同的字符串,至多只有一个位置不相同,问长度为 m 的 01 串中,有多少个字符串,存在一个长度为 n ...

  4. HDU - 2825 Wireless Password(AC自动机+状压dp)

    题目链接:点击查看 题目大意:给出 m 个匹配串,问长度为 n 的字符串中,至少包含 k 个匹配串(可重叠)的字符串有多少个 题目分析:考虑到n,m,k都特别小,所以可以先用AC自动机将状态关系转移出 ...

  5. YBT 2.4 AC自动机

    其实这个专题NOIP几乎不考 AC自动机,就是能让题自动AC的东西,是不是十分神奇 对的,就是这么神奇 AC自动机是解决多模式串与文本串匹配的问题 是KMP+Trie树的结合,也是一个毒瘤算法 Key ...

  6. POJ - 1625 Censored!(AC自动机+dp+高精度运算)

    题目链接:点击查看 题目大意:给出一个含有 n 个不同字符的字符集,接着规定所有单词的长度为 m ,再给出 k 个病毒串,问有多少个字符串中不含有病毒串 题目分析:这个题目和之前做过的DNA的那个题有 ...

  7. AC自动机笔记与例题整理

    TP KMP AC自动机建树/图 最后就是例题时间: 搜索关键词 单词 设计密码 修复DNA Codeforces16届黑龙江省赛E题 洛谷:阿狸打字机(经典自动机,fail树上数据结构维护信息) [ ...

  8. Aho-Corasick 多模式匹配算法(AC自动机) 的算法详解及具体实现

    多模式匹配 多模式匹配就是有多个模式串P1,P2,P3-,Pm,求出所有这些模式串在连续文本T1-.n中的所有可能出现的位置. 例如:求出模式集合{"nihao","ha ...

  9. 【BZOJ2434】[NOI2011]阿狸的打字机 AC自动机+DFS序+树状数组

    [BZOJ2434][NOI2011]阿狸的打字机 Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P ...

最新文章

  1. 前端面试题整理(定期更新)
  2. MySQL语句相关经验总结
  3. node mysql 多个_使用Node.js处理多个MySQL查询
  4. 构造函数和析构函数能不能是虚函数
  5. python数据生成正态分布图_Python 与金融数据生成机器学习的特征数据
  6. 数据结构及算法学习——写在前面的话
  7. Where is ABAP Netweaver HTTP 304 not modified set
  8. McAfee:较之中国美国黑客才最令人害怕
  9. Entity Framework Core 懒加载
  10. 【渝粤教育】广东开放大学 Photoshop 图像处理 形成性考核 (24)
  11. 开工了,为自己做的软件。先做些控件。
  12. 使用Spyder控制台(console)执行带参数脚本和带参数的debug模式
  13. Android Studio3.5 JAVA调用C++源码方法总结
  14. #转载汉化 用C++写出来的人工智能围棋游戏
  15. java版 简易斗地主(三)
  16. tplinkwr710n改无线打印服务器,TP-Link TL-WR710N V1无线路由器AP模式设置
  17. selenium click点击无反应问题
  18. 对计算机的磁盘进行维护,电脑硬盘如何进行维护?
  19. NLP-文本向量训练及相似度计算
  20. margin:0 auto是什么意思

热门文章

  1. 科技公司的中台战略:理念溯源、组织边界及其实施之道∣企鹅经济学
  2. 聪颖少年——李耳少年求学好问爱思考的故事:写出流传千古的《道德经》的老子...
  3. 美股市场ETF的中文名列表
  4. 艾为数字ic面试题_国外的数字IC面试题(非常详细,有答案)
  5. GMAT数学拿不到50/51的人都点开这篇文章!
  6. 高完整性系统工程(十一):Fault Tolerant Design
  7. JS实现小球移动(点击移动,点击停止)
  8. Bayes deep learning的理解
  9. iOS 第三方应用调用safari---------杭州卓健信息科技有限公司
  10. 如何打出带有音调的拼音字母