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

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. 常用linq语法

    1.简单的linq语法 var ss = from r in db.Am_recProScheme select r; var ss1 = db.Am_recProScheme; string sss ...

  2. apidemos编译出错

    编译api 19的(4.4.2)apidemos一直报xml相关资源出错. 把build-toos 22删除,替换成19版本的,就ok了. 真是坑啊. 学习新东西难免遇到坑.

  3. JavaScript callback function 理解

    看到segmentfault上的这个问题 JavaScript 回调函数怎么理解,觉得大家把异步和回调的概念混淆在一起了.做了回答: 我觉得大家有点把回调(callback)和异步(asynchron ...

  4. PHP通过curl模拟POST上传文件,5.5之前和之后的区别

    首先先要着重提一下,只要是做和项目有关的开发,首先按把环境中各个服务的版本保持一致,否则出些莫名其妙的错我,让你百爪挠心却不知哪里的问题.这里就要说下curl_setopt($ch, CURLOPT_ ...

  5. Django - Jsonp、CORS

    一.同源策略 https://www.cnblogs.com/yuanchenqi/articles/7638956.html 同源策略(Same origin policy)是一种约定,它是浏览器最 ...

  6. docker 数据管理数据卷

    1,数据卷 数据卷是一个可供容器使用特殊目录,他将主机操作系统目录直接映射容器 1,在容器内创建一个数据卷 在使用docker run命令的时候,使用-v标记就可以创建一个数据卷,多次重复使用-v可以 ...

  7. uchome四大常用入口文件

    一.四大常用入口文件 cp.php           编辑日志.相册.活动等等相关编辑操作基本上都从这个文件入口 do.php          登录.注册.找回密码.相册批量上传.在需要密码的情况 ...

  8. 使用JAVA实现语音朗读一段文本

    需要做的工作: 1.下载  jacob-1.17-M2 或 jacob-1.18 2.解压jacob-1.17-M2 或 jacob-1.18 3.向工程里导入jacob.jar 4.将 jacob- ...

  9. Python中被双下划线包围的魔法方法

    基本的魔法方法 __new__(cls[, ...]) 用来创建对象 1. __new__ 是在一个对象实例化的时候所调用的第一个方法 2. 它的第一个参数是这个类,其他的参数是用来直接传递给 __i ...

  10. 在GUI程序中使用控制台的两种方法

    win32程序启用控制台(控制台文件名:conout$,conin$,conerr$) //添加控制台,加入在程序构造函数中 AllocConsole(); freopen("conin$& ...