小明系列故事——女友的考验

Time Limit: 500/200 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 2024    Accepted Submission(s): 556

Problem 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!” (引号不用输出)。
 
Sample Input
3 1
1 1
2 1
3 1
2
1 2

2 1
0 0
1 1
2
1 2

5 3
0 0
5 3
1 2
1 22
5 21
3
1 2 3
2
4 5
2
1 5

0 0

 
Sample Output
2.00
Can not be reached!
21.65
 
Source
 
    将女友的要求建ac自动机,然后在树上匹配,f[i][j]表示在i号点对应树上的状态j时候的最短路(从1开始),WA了半天原来是bfs的时候忘记把以失配指针的为结尾的单词状态转移到当前节点上,比如1-2-3-4 ,2-3 , 第一条路径上的'3'显然应该被标记为不能走的路(由于包含了禁路"2-3"),= =还是掌握的不熟练啊。
  

 #include<iostream>
#include<cstring>
#include<queue>
#include<cstdio>
#include<stack>
#include<set>
#include<map>
#include<cmath>
#include<ctime>
#include<time.h>
#include<algorithm>
using namespace std;
#define mp make_pair
#define pb push_back
#define debug puts("debug")
#define LL long long
#define pii pair<int,int>
#define eps 1e-10
double inf=1e20;
int N;
struct Point{
double x,y;
}P[];
double dis(Point A,Point B){
return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
}
double e[][];
struct ach{
int ch[][],fail[],cnt[],tot;
double f[][];
void init(){
tot=;
newnode();
} int newnode(){
memset(ch[tot],-,sizeof(ch[tot]));
fail[tot]=-;
cnt[tot]=;
return tot++;
} void insert(int a[],int n){
int u=;
for(int i=;i<=n;++i){
if(ch[u][a[i]]==-) ch[u][a[i]]=newnode();
u=ch[u][a[i]];
}
cnt[u]=;
}
void getfail(){
queue<int>q;
fail[]=;
for(int i=;i<=N;++i){
if(ch[][i]==-){
ch[][i]=;
}
else{
fail[ch[][i]]=;
q.push(ch[][i]);
}
}
while(!q.empty()){
int u=q.front();
q.pop();
cnt[u]|=cnt[fail[u]];
for(int i=;i<=N;++i){
if(ch[u][i]==-){
ch[u][i]=ch[fail[u]][i];
}
else{
fail[ch[u][i]]=ch[fail[u]][i];
q.push(ch[u][i]);
}
}
}
} void solve(){
for(int i=;i<=N;++i){
for(int j=;j<tot;++j){
f[i][j]=inf;
}
}
f[][ch[][]]=;
for(int i=;i<=N;++i){
for(int j=;j<tot;++j){
if(f[i][j]<inf){
for(int k=i+;k<=N;++k){
if(cnt[ch[j][k]]==){
f[k][ch[j][k]]=min(f[k][ch[j][k]],f[i][j]+e[i][k]);
}
}
}
}
} double ans=inf;
for(int j=;j<tot;++j)
ans=min(ans,f[N][j]);
if(ans==inf) puts("Can not be reached!");
else printf("%.2f\n",ans);
}
}a;
int main()
{
int n,m,i,j,k;
int c[];
while(cin>>n>>m){N=n;
a.init();
if(n==&&m==) break;
for(i=;i<=n;++i) {e[i][i]=;
scanf("%lf%lf",&P[i].x,&P[i].y);
for(j=;j<i;++j){
e[i][j]=e[j][i]=dis(P[i],P[j]);
}
}
for(i=;i<=m;++i){
scanf("%d",&k);
for(j=;j<=k;++j){
scanf("%d",c+j);
}
a.insert(c,k);
} a.getfail();
a.solve();
}
return ;
}

HDU-4511-ac自动机+dp的更多相关文章

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

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

  2. hdu 2457(ac自动机+dp)

    题意:容易理解... 分析:这是一道比较简单的ac自动机+dp的题了,直接上代码. 代码实现: #include<stdio.h> #include<string.h> #in ...

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

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

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

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

  5. HDU 2825 AC自动机+DP

    题意:一个密码,长度为 n,然后有m个magic words,这个密码至少由k个magic words组成. 问这个密码可能出现的总数. 思路:首先构造AC自动机,由于m很小,才10 ,我们可以使用二 ...

  6. Lost's revenge HDU - 3341 AC自动机+DP(需要学会如何优雅的压缩状态)

    题意: 给你n个子串和一个母串,让你重排母串最多能得到多少个子串出现在重排后的母串中. 首先第一步肯定是获取母串中每个字母出现的次数,只有A T C G四种. 这个很容易想到一个dp状态dp[i][A ...

  7. DNA repair HDU - 2457 AC自动机+DP

    题意: 给你N个模板串,并且给你一个文本串, 现在问你这个文本串最少需要改变几个字符才能使得它不包含任何模板串. (以上字符只由A,T,G,C构成) 题解: 刚开始做这一题的时候表示很懵逼,好像没有学 ...

  8. hdu 4511 (AC自动机)

    注意标记一个点后,fail树上的子节点都会被标记 跑spfa,dp也可以 #include<iostream> #include<cstdio> #include<str ...

  9. HDU 2425 DNA repair (AC自动机+DP)

    DNA repair Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  10. HDU 3341 Lost's revenge AC自动机+dp

    Lost's revenge Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)T ...

随机推荐

  1. Redis的一些结构

  2. ISCC2016-BASIC、WEB、MISC简单writeup

    RE和PWN题目的wp有大神已经放出来了,我也不擅长,就不搬了.bin求带. BASIC BASIC-1 50 仿射函数,百度“仿射加密法”,它讲的够清楚了. BASIC-2 50 结尾的“=”这个特 ...

  3. ZOHO 免费小型企业邮箱和个人邮箱

    Zoho Mail 提供免费小型企业邮箱注册.精简版只能添加一个域到您的机构帐号,最多允许10用户.如果您想添加多个域,您可以升级到标准版.10用户免费,5 GB /每用户,5 GB (共享). 除了 ...

  4. L1正则与L2正则

    L1正则是权值的绝对值之和,重点在于可以稀疏化,使得部分权值等于零. L1正则的含义是 ∥w∥≤c,如下图就可以解释为什么会出现权值为零的情况. L1正则在梯度下降的时候不可以直接求导,可以有以下几种 ...

  5. 什么是API测试

    什么是API API是Application Programming Interface的简写. 实现了两个或多个独立系统或模块间的通信和数据交换能力. 什么是API测试 图片.png API测试是不 ...

  6. 4.1 Routing -- Introduction

    一.Routing 1. 当用户与应用程序交互时,它会经过很多状态.Ember.js为你提供了有用的工具去管理它的状态和扩展你的app. 2. 要理解为什么这是重要的,假设我们正在编写一个Web应用程 ...

  7. Java 动态代理是基于什么原理

    动态代理 ①动态代理概念理解 动态代理是一种方便运行时动态构建代理.动态处理代理方法调用的机制,很多场景都利用类似机制做到的,比如用来包装RPC调用.面向切面的变成(AOP) 实现动态代理的方式很多, ...

  8. Flume同时输出数据到HDFS和kafka

    cd /usr/local/flume/conf vim flume-exec-total.conf ## Explain #通过sink把数据分别输出到kafka和HDFS上 # Name the ...

  9. bzoj1612 / P2419 [USACO08JAN]牛大赛Cow Contest(Floyd)

    P2419 [USACO08JAN]牛大赛Cow Contest Floyd不仅可以算最短路,还可以处理点之间的关系. 跑一遍Floyd,处理出每个点之间是否有直接或间接的关系. 如果某个点和其他$n ...

  10. Installing VirtualBox DKMS in Kali 2.0

    Kali linux is one of the mainly used operating system by the Ethical hackers and information securit ...