注意标记一个点后,fail树上的子节点都会被标记

跑spfa,dp也可以

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include <set>
#include <queue>
#define ll long long
#define ld long double
#define lson l,m,rt<<1
#define pi acos(-1)
#define rson m+1,r,rt<<1|1
#define fo(i,l,r) for(int i = l;i <= r;i++)
#define fd(i,l,r) for(int i = r;i >= l;i--)
#define mem(x) memset(x,0,sizeof(x))
#define eps 1e-8
using namespace std;
const int maxn = ;
const ll inf = 1e9;
const ll mod = ;
ll read() {
ll x=,f=;
char ch=getchar();
while(!(ch>=''&&ch<='')) {
if(ch=='-')f=-;
ch=getchar();
};
while(ch>=''&&ch<='') {
x=x*+(ch-'');
ch=getchar();
};
return x*f;
}
struct Trie{
int nxt[maxn][],fail[maxn],end[maxn];
int root,L;
int newnode(){
for(int i = ;i < ;i++)
nxt[L][i] = -;
end[L++]=;
return L-;
}
void init(){
L = ;
root = newnode();
}
void insert(char buf[],bool bj){
int len = strlen(buf);
int now = root;
for(int i = ;i < len;i++){
if(nxt[now][buf[i]]==-)
nxt[now][buf[i]] = newnode();
now = nxt[now][buf[i]];
}
if(bj)end[now]++;
}
void build(){
queue<int> Q;
fail[root] = root;
for(int i = ;i < ;i++) {
if (nxt[root][i] == -) {
nxt[root][i] = root;
} else {
fail[nxt[root][i]] = root;
Q.push((nxt[root][i]));
}
}
while(!Q.empty()){
int now = Q.front();
Q.pop();
if(end[fail[now]]) end[now]=;
for(int i = ;i < ;i++){
if(nxt[now][i]==-) {
nxt[now][i] = nxt[fail[now]][i];
}else{
fail[nxt[now][i]] = nxt[fail[now]][i];
Q.push(nxt[now][i]);
}
}
}
}
}ac;
int n,m,k;
double xx[maxn],yy[maxn];
char s[];
struct dat{
int u;
int v;
double dis;
}now,nxt;
vector<dat> g[][];
double d[][];
bool vis[][];
double ans;
void spfa(){
queue<dat> q;
fo(i,,ac.L-){
fo(j,,n){
vis[i][j]=false;
d[i][j]=-100.0;
}
}
now.u = ac.nxt[][];now.v=;
q.push(now);
vis[now.u][]=true;d[now.u][]=0.0;
while(!q.empty()){
now = q.front();
q.pop();
for(dat t:g[now.u][now.v]){
if(d[t.u][t.v]<||(d[now.u][now.v]+t.dis<d[t.u][t.v])){
d[t.u][t.v] = d[now.u][now.v]+t.dis;
if(!vis[t.u][t.v]){
vis[t.u][t.v]=true;
q.push(t);
}
}
}
if(now.v==n){
if(ans<||d[now.u][now.v] <ans)ans=d[now.u][now.v];
}
vis[now.u][now.v]=false;
} }
int main() {
while(true){
ac.init();
ans=-1.0;
n=read();m=read();
if(!n&&!m)break;
fo(i,,n){
xx[i]=read();yy[i]=read();
}
fo(i,,m){
k=read();
int t;
fo(j,,k){
t=read();
s[j-]=t;
}
s[k]='\0';
ac.insert(s,true);
}
ac.build();
int v; fo(i,,ac.L-){
fo(j,,n) g[i][j].clear();
fo(j,,n){
v=ac.nxt[i][j];
if(ac.end[v])continue;
now.u = v;
now.v = j;
fo(k,,n){
if(k>=j)continue;
now.dis = sqrt((xx[j]-xx[k])*(xx[j]-xx[k]) + (yy[j]-yy[k])*(yy[j]-yy[k]));
g[i][k].push_back(now);
}
}
}
spfa();
if(fabs(ans)<eps)ans=;
if(ans<-eps)puts("Can not be reached!");
else printf("%.2f\n",ans);
}
return ;
}

hdu 4511 (AC自动机)的更多相关文章

  1. HDU 4511 (AC自动机+状态压缩DP)

    题目链接:  http://acm.hdu.edu.cn/showproblem.php?pid=4511 题目大意:从1走到N,中间可以选择性经过某些点,比如1->N,或1->2-> ...

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

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

  3. hdu 2896 AC自动机

    // hdu 2896 AC自动机 // // 题目大意: // // 给你n个短串,然后给你q串长字符串,要求每个长字符串中 // 是否出现短串,出现的短串各是什么 // // 解题思路: // / ...

  4. hdu 3065 AC自动机

    // hdu 3065 AC自动机 // // 题目大意: // // 给你n个短串,然后给你一个长串,问:各个短串在长串中,出现了多少次 // // 解题思路: // // AC自动机,插入,构建, ...

  5. hdu 5880 AC自动机

    Family View Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

  6. hdu 2296 aC自动机+dp(得到价值最大的字符串)

    Ring Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  7. hdu 2825 aC自动机+状压dp

    Wireless Password Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  8. hdu 3065 AC自动机(各子串出现的次数)

    病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  9. HDU 5384 AC自动机

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=5384 题意:给n个母串,给m个匹配串,求每个母串依次和匹配串匹配,能得到的数目和. 分析:之前并不知道AC ...

随机推荐

  1. Vue的双向数据绑定的原理

    Vue数据双向绑定的原理就是采用数据劫持结合发布者-订阅者模式,通过object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监 ...

  2. Input常用的输入框验证(正则)

    1.只是不能输入空格 <input type="text" οnkeyup="this.value=this.value.replace(/^ +| +$/g,'' ...

  3. java线程中的同步锁和互斥锁有什么区别?

    两者都包括对资源的独占. 区别是 1:互斥是通过竞争对资源的独占使用,彼此没有什么关系,也没有固定的执行顺序. 2:同步是线程通过一定的逻辑顺序占有资源,有一定的合作关系去完成任务.

  4. iptables-save - 保存 IP Tables

    总览 SYNOPSIS iptables-save [-c] [-t table] 描述 DESCRIPTION iptables-save 用来将 IP Table 转储为可以简单解析的格式,输出到 ...

  5. 使用IL DASM来查看接口内的自动属性

    在我的本地地址中 C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.2 Tools\x64下有一个文件  ildas ...

  6. Wasserstein Generative Adversarial Nets (WGAN ) and CGAN

    GAN目前是机器学习中非常受欢迎的研究方向.主要包括有两种类型的研究,一种是将GAN用于有趣的问题,另一种是试图增加GAN的模型稳定性. 事实上,稳定性在GAN训练中是非常重要的.起初的GAN模型在训 ...

  7. [project X] tiny210(s5pv210)上电启动流程(BL0-BL2)(转)

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/ooonebook/article/det ...

  8. RabbitMQ 启用页面管理功能并设置权限

    RabbitMQ 启用页面管理功能并设置权限 RabbitMQ guest administrator  在安装完 rabbitmq 后,默认有一个 guest/guest 账号密码,但是为了安全,此 ...

  9. 设计模式Design Pattern(4) -- 访问者模式

    什么是访问者模式? 一个对象有稳定的数据结构,却为不同的访问者提供不同的数据操作,对象提供接收访问者的方法,从而保证数据结构的稳定性和操作的多样性.也可以理解为,封装对象的操作方法,达到不改变对象数据 ...

  10. jmeter使用jdbc获取注册验证码进行注册

    自动化工具测试注册功能时,往往会遇到验证码,这个烦人的验证码怎么能够解决掉呢? 通常有两种方法 让开发禁用注册码,或在测试环境写个固定的验证码 在jmeter中用 jdbc获取数据库中验证码 今天通过 ...