题意 :  给出编号从1 ~ n 的 n 个平面直角坐标系上的点,求从给出的第一个点出发到达最后一个点的最短路径,其中有两种限制,其一就是只能从编号小的点到达编号大的点,再者不能走接下来给出的 m 个限制路径,也就是其中有些路线无法走。

分析 : 把问题抽象一下就是用编号 1 ~ n 构造一个字符串,使得字符串不包含 m 个给出的子串,且构造的代价是最小的 ( 两点间距就是代价,也就是路长 )。那如果做了很多有关在 Trie图 || AC自动机上DP的题目,那这道题就使用很套路的方法就可以了。先将给出的 m 个路线丢去构建 Trie 图,然后定义 DP[i][j] = 在编号为 i 的点 且 在 Trie 图上编号为 j 的节点状态下,最短的路径长度是多少,则可得转移方程

DP[i+1][k] = min( DP[i+1][k], DP[i][j] + GetDis(i, k) ) 且 i+1 <= k <= n (保证编号从小到大)

其中 GetDis(i, k) 是坐标点 i 和 k 的距离、而且 Trie[j].Next[k].flag == 0 即在 Trie 图上 j 状态到 k 状态合法,并不会使其包含非法路径

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<math.h>
using namespace std;
;
;
const double INF = 1e20;///不能使用 0x3f3f3f3f
int n, m;
pair<];
struct Aho{
    struct StateTable{
        int Next[Letter];
        int fail, flag;
    }Node[Max_Tot];
    int Size;
    queue<int> que;

    inline void init(){
        while(!que.empty()) que.pop();
        memset(Node[].Next, , ].Next));
        Node[].fail = Node[].flag = ;
        Size = ;
    }

    inline void insert(int *s, int len){
        ;
        ; i<len; i++){
            int idx = s[i];
            if(!Node[now].Next[idx]){
                memset(Node[Size].Next, , sizeof(Node[Size].Next));
                Node[Size].fail = Node[Size].flag = ;
                Node[now].Next[idx] = Size++;
            }
            now = Node[now].Next[idx];
        }
        Node[now].flag = ;
    }

    inline void BuildFail(){
        Node[].fail = ;
        ; i<n; i++){
            ].Next[i]){
                Node[Node[].Next[i]].fail = ;
                que.push(Node[].Next[i]);
            }].Next[i] = ;///必定指向根节点
        }
        while(!que.empty()){
            int top = que.front(); que.pop();
            Node[top].flag |= Node[Node[top].fail].flag;///注意了!!
            ; i<n; i++){
                int &v = Node[top].Next[i];
                if(v){
                    que.push(v);
                    Node[v].fail = Node[Node[top].fail].Next[i];
                }else v = Node[Node[top].fail].Next[i];
            }
        }
    }
}ac;

double GetDis(pair<int,int> &st, pair<int,int> &en)
{
    double x1 =  (double)st.first;
    double x2 =  (double)en.first;
    double y1 =  (double)st.second;
    double y2 =  (double)en.second;
    return sqrt( (double)(1.0*x1-x2)*(double)(1.0*x1-x2) +
                 (double)(1.0*y1-y2)*(double)(1.0*y1-y2));
}

][];
inline void Solve()
{

    ; i<n; i++)
        ; j<ac.Size; j++)
            dp[i][j] = INF;

    dp[][ac.Node[].Next[]] = ;
    ; i<n-; i++){
        ; j<ac.Size; j++){
            if(dp[i][j] < INF){
                ; k<n; k++){
                    int newi = k;
                    int newj = ac.Node[j].Next[k];
                    if(!ac.Node[ newj ].flag){
                        dp[newi][newj] = min(dp[newi][newj],
                                             dp[i][j]+GetDis(Point[i], Point[k]));
                    }
                }
            }
        }
    }

    double ans = INF;
    ; i<ac.Size; i++)
        ][i] < INF)
            ans = min(ans, dp[n-][i]);

    if(ans == INF) puts("Can not be reached!");
    else printf("%.2lf\n", ans);
}

int main(void)
{
    while(~scanf("%d %d", &n, &m)){
         && m==) break;
        ; i<n; i++)///这里我将编号 -1 了,也就是编号从 0 ~ n-1,所以下面操作都是按个编号来
            scanf("%d %d", &Point[i].first, &Point[i].second);
        ];
        ac.init();
        while(m--){
            int k;
            scanf("%d", &k);
            ; i<k; i++){
                scanf("%d", &tmp[i]);
                tmp[i]--;///因为编号是 0 ~ n-1
            }
            ac.insert(tmp, k);
        }ac.BuildFail();
        Solve();
    }
    ;
}

HDU 4511 小明系列故事——女友的考验 ( Trie图 && DP )的更多相关文章

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

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

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

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

  3. HDU - 4511 小明系列故事――女友的考验(AC自己主动机+DP)

    Description 最终放寒假了,小明要和女朋友一起去看电影.这天,女朋友想给小明一个考验,在小明正准备出发的时候.女朋友告诉他.她在电影院等他,小明过来的路线必须满足给定的规则:  1.如果小明 ...

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

    题意:从 1 走到 n,要求所走路径不能出现给定的路径,求最短路 思路:因为要求不能出现给定路径,那么我可以求助ac自动机完成判断. 我们可以在build的时候标记哪些路径不能出现,显然下面这种表示后 ...

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

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

  6. 小明系列故事――女友的考验 HDU - 4511 AC自动机+简单DP

    题意:自己看题目,中文体面. 题解: 把所有不能走的路径放入AC自动机中. 然后DP[i][j]表示走到 i 这个点,且位于AC自动机 j 这个节点最短距离 然后直接DP即可.注意一点会爆int #i ...

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

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

  8. hdu4511小明系列故事——女友的考验(ac自动机+最短路)

    链接 预处理出来任意两点的距离,然后可以顺着trie树中的节点走,不能走到不合法的地方,另开一维表示走到了哪里,依次来更新. 注意判断一下起点是不是合法. #include <iostream& ...

  9. HDU-4511 小明系列故事——女友的考验 floyd变种-标号递增最短路

    题意:给定N个点,现在要求出从1号点到N号点的最短路.题目给的限制条件就是对于某条路径是不能够走的,但是可以选择某段路径走,另外就是所走的路径的标号必须是递增的. 分析:由于给定的是一些列的坐标点,这 ...

随机推荐

  1. mysql5.7无法启动原因排查

    前天刚刚拷了同事最新的MySQL5.7,安装成功后运行良好,今天却无法启动,Navicat也无法连接. 开始排查原因: 1.进入dos命令窗口,输入net start mysql启动,提示 百度出现错 ...

  2. jmeter线程组基本设置

    线程组基本设置 在线程组界面中可以设置以下数据,进行控制线程组: 1.取样器错误后要执行的动作: 继续:忽略错误,继续执行 Start Next Thread Loop: 忽略错误,线程当前循环终止, ...

  3. cocos2dx基础篇(14) 滚动视图CCScrollView

    [3.x]     (1)去掉 "CC"     (2)滚动方向         > CCScrollViewDirection 改为强枚举 ScrollView::Dire ...

  4. xmake v2.2.9 发布, 新增c++20 modules的实验性支持

    这个版本没啥太大新特性,主要对c++20 modules进行了实验性支持,目前支持clang/msvc编译器,除此之外改进了不少使用体验,并且提高了一些稳定性. 另外,这个版本新增了socket.io ...

  5. docker私有仓库-harbor

    简单说一下Harbor的部署,踩了几个坑,参考同事大神的配置文件,一脸懵逼的部署出来了,其中部分内容参考了网上一些大神的文档,本篇文章仅供参考学习,如有雷同,万分荣幸. 这篇文档仅限于centos7参 ...

  6. linux系统中不小心执行了rm -rf ./* 怎么办?解决:文件系统的备份与恢复

    XFS提供了 xfsdump 和 xfsrestore 工具协助备份XFS文件系统中的数据.xfsdump 按inode顺序备份一个XFS文件系统.centos7选择xfs格式作为默认文件系统,而且不 ...

  7. Java并发编程:锁的释放

    Java并发编程:锁的释放 */--> code {color: #FF0000} pre.src {background-color: #002b36; color: #839496;} Ja ...

  8. ThinkPHP5 与 composer

    我是通过安装composer来获取tp5安装的,也是学习一下 在 Windows 中,你需要下载并运行 Composer-Setup.exe. 安装时,要选择本地环境中php.exe作为跟目录,这个可 ...

  9. 「POI2010」反对称 Antisymmetry (manacher算法)

    # 2452. 「POI2010」反对称 Antisymmetry [题目描述] 对于一个 $0/1$ 字符串,如果将这个字符串 $0$ 和 $1$ 取反后,再将整个串反过来和原串一样,就称作「反对称 ...

  10. 洛谷 - P1522 - 牛的旅行 - Cow Tours - Floyd

    https://www.luogu.org/problem/P1522 好坑啊,居然还有直径不通过新边的数据,还好不是很多. 注意一定要等Floyd跑完之后再去找连通块的直径,不然一定是INF. #i ...