HDU 4511 小明系列故事——女友的考验 (AC自动机 + DP)题解
题意:从 1 走到 n,要求所走路径不能出现给定的路径,求最短路
思路:因为要求不能出现给定路径,那么我可以求助ac自动机完成判断。
我们可以在build的时候标记哪些路径不能出现,显然下面这种表示后缀不能出现,那么他也不能出现
if(node[node[u].fail].cnt && u) node[u].cnt = 1; //都不能取
然后再把图建完整。因为如果一个路径不在Trie中有两种情况,一种是他可能是某个不能走的串的前缀,那么我就重新指向这个不能走的串,比如Trie中只有AT,那么我走ATA相当于走AT再走回A;另一种是这个路径根本没出现过,那么相当于从0开始走。
if(!node[u].next[i]){if(u == 0)node[u].next[i] = 0;elsenode[u].next[i] = node[node[u].fail].next[i]; }
dp[i][j]表示走到i点在AC自动机上走到j点的最小路径。
代码:
#include<cmath> #include<set> #include<map> #include<queue> #include<cstdio> #include<vector> #include<cstring> #include <iostream> #include<algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; const int maxn = 500 + 5; const int M = 50 + 5; const ull seed = 131; const double INF = 1e20; const int MOD = 1000000007; double x[M], y[M]; int s[M]; double dp[M][maxn]; int m, n; double dis(int i, int j){return sqrt((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j])); } struct Aho{struct state{int next[M];int fail, cnt;}node[maxn];int size;queue<int> q;void init(){size = 0;newtrie();while(!q.empty()) q.pop();}int newtrie(){memset(node[size].next, 0, sizeof(node[size].next));node[size].cnt = node[size].fail = 0;return size++;}void insert(int s[], int len){int now = 0;for(int i = 0; i < len; i++){int c = s[i];if(node[now].next[c] == 0){node[now].next[c] = newtrie();}now = node[now].next[c];}node[now].cnt = 1;}void build(){node[0].fail = -1;q.push(0);while(!q.empty()){int u = q.front();q.pop();if(node[node[u].fail].cnt && u) node[u].cnt = 1; //都不能取for(int i = 0; i <= n; i++){if(!node[u].next[i]){if(u == 0)node[u].next[i] = 0;elsenode[u].next[i] = node[node[u].fail].next[i];}else{if(u == 0) node[node[u].next[i]].fail = 0;else{int v = node[u].fail;while(v != -1){if(node[v].next[i]){node[node[u].next[i]].fail = node[v].next[i];break;}v = node[v].fail;}if(v == -1) node[node[u].next[i]].fail = 0;}q.push(node[u].next[i]);}}}}void query(){for(int i = 0; i <= n; i++){for(int j = 0; j < size; j++){dp[i][j] = INF;}}dp[1][node[0].next[1]] = 0;for(int i = 1; i <= n; i++){for(int j = 0; j < size; j++){if(dp[i][j] == INF) continue;for(int k = i + 1; k <= n; k++){if(node[node[j].next[k]].cnt) continue;dp[k][node[j].next[k]] = min(dp[k][node[j].next[k]], dp[i][j] + dis(i, k));}}}double ans = INF;for(int i = 0; i < size; i++)if(dp[n][i] < INF) ans = min(ans, dp[n][i]);if(ans == INF) printf("Can not be reached!\n");else printf("%.2f\n", ans);}}ac; int main(){while(~scanf("%d%d", &n, &m) && n + m){for(int i = 1; i <= n; i++){scanf("%lf%lf", &x[i], &y[i]);}ac.init();while(m--){int k;scanf("%d", &k);for(int i = 0; i < k; i++){scanf("%d", &s[i]);}ac.insert(s, k);}ac.build();ac.query();}return 0; }
转载于:https://www.cnblogs.com/KirinSB/p/11180002.html
HDU 4511 小明系列故事——女友的考验 (AC自动机 + DP)题解相关推荐
- HDU - 4511 小明系列故事——女友的考验(AC自动机+dp)
题目链接:点击查看 题目大意:小明在点 1 而小明的女朋友在点 n ,现在小明要去找女朋友,满足以下两个条件: 途径的序号满足严格递增 小明的女朋友给小明提出了 m 条路径是不允许走的 在满足上述两条 ...
- HDU 4511 小明系列故事——女友的考验 ( Trie图 DP )
题意 : 给出编号从1 ~ n 的 n 个平面直角坐标系上的点,求从给出的第一个点出发到达最后一个点的最短路径,其中有两种限制,其一就是只能从编号小的点到达编号大的点,再者不能走接下来给出的 m 个 ...
- 【HDU 4511】小明系列故事——女友的考验(AC自动机+DP)
Problem Description 终于放寒假了,小明要和女朋友一起去看电影.这天,女朋友想给小明一个考验,在小明正准备出发的时候,女朋友告诉他,她在电影院等他,小明过来的路线必须满足给定的规则: ...
- 小明系列故事——女友的考验
Problem Description 终于放寒假了,小明要和女朋友一起去看电影.这天,女朋友想给小明一个考验,在小明正准备出发的时候,女朋友告诉他,她在电影院等他,小明过来的路线必须满足给定的规则: ...
- hdu 4501 小明系列故事——买年货 多重背包
小明系列故事--买年货 Time Limit: 500 ...
- hdu 4506 小明系列故事——师兄帮帮忙
小明系列故事--师兄帮帮忙 Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other) Total ...
- HDU 4506 小明系列故事——师兄帮帮忙
小明系列故事--师兄帮帮忙 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) To ...
- HDU 4501 小明系列故事——买年货
小明系列故事--买年货 Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Tota ...
- HDU 4528 小明系列故事——捉迷藏
题目链接~~> 做题感悟:这题需要逆向思维,先预处理一下就好. 解题思路:先预处理一下将可以看到 D 与 E 的点标记一下,这样 bfs()遍历迷宫时就可以节省很多时间,还要注意:可以重复走走过 ...
- hdu 4528小明系列故事——捉迷藏
题目:点击打开链接 宽搜.注意判重.判重导致比赛的时候错了两次. #include <cmath> #include <ctime> #include <iostream ...
最新文章
- 我同事说我写代码像写诗
- 荣耀v40鸿蒙5g,荣耀V40pro再曝光,4K屏+双5000万+鸿蒙OS,再见了荣耀V30pro
- python-opencv怎样找到要跟踪对象的HSV
- ELK+Kafka集群日志分析系统
- upload-labs_pass10_点空点绕过_pass11_双写文件扩展名
- c++ cstring 转换 char_Java基本数据类型的介绍及其转换(内附字符串与多种数据之间的转换)...
- 关于CMS垃圾回收器的几个问题
- 解决复杂问题的思路 —— 从简单到复杂
- Boring Old Menu Bar for Mac(Big Sur菜单栏优化工具)
- Http请求之基于HttpUrlConnection,支持Header,Body传值,支持Multipart上传文件:
- NULL 与 nullptr区别与联系
- mysql relay_mysql relay log参数汇总
- c语言 猜字游戏,【c语言】 小游戏――猜字游戏
- Tell Me Where to Look: Guided Attention Inference Network论文翻译
- 再获喜讯,思迈特软件入选2021企业数智化转型升级服务全景图
- 2019NEFU寒假集训新生考试 2020.1.6
- 瑞芯微RK3328硬件设计指南
- c++逆天改命进阶--二叉树练习题
- 从街机到抓娃娃机,硬币经济也将被移动支付取代?
- 在Ubuntu中安装Chrome浏览器