HDU 4511 小明系列故事——女友的考验(自动机+DP)
2015-04-21 00:48
435 查看
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
Sample Output
状态也很好想,设dp[i][j]代表走到i节点,在自动机上状态为j时的最小花费。
终于放寒假了,小明要和女朋友一起去看电影。这天,女朋友想给小明一个考验,在小明正准备出发的时候,女朋友告诉他,她在电影院等他,小明过来的路线必须满足给定的规则:
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
状态也很好想,设dp[i][j]代表走到i节点,在自动机上状态为j时的最小花费。
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<string> #include<iostream> #include<queue> #include<cmath> #include<map> #include<stack> #include<bitset> using namespace std; #define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i ) #define REP( i , n ) for ( int i = 0 ; i < n ; ++ i ) #define CLEAR( a , x ) memset ( a , x , sizeof a ) typedef long long LL; typedef pair<int,int>pil; const double INF = 1e20; struct node{ int x,y; }e[110]; double dp[55][1100]; int n,m; double dis(node l1,node l2) { return sqrt((double)(1.0*l1.x-l2.x)*(1.0*l1.x-l2.x)+(double)(1.0*l1.y-l2.y)*(1.0*l1.y-l2.y)); } struct AC{ int next[1100][55]; int fail[1100]; int ed[1100]; int root,L; int newnode() { for(int i=1;i<=n;i++) next[L][i]=-1; ed[L++]=0; return L-1; } void init() { L=0; root=newnode(); } void Insert(char buf[]) { int len=strlen(buf); int now=root; for(int i=0;i<len;i++) { int id=buf[i]-'0'; if(next[now][id]==-1) next[now][id]=newnode(); now=next[now][id]; } ed[now]=1; } void Build_AC() { queue<int>q; fail[root]=root; for(int i=1;i<=n;i++) { if(next[root][i]==-1) next[root][i]=root; else { fail[next[root][i]]=root; q.push(next[root][i]); } } while(!q.empty()) { int now=q.front(); q.pop(); ed[now]|=ed[fail[now]]; for(int i=1;i<=n;i++) { if(next[now][i]==-1) next[now][i]=next[fail[now]][i]; else { fail[next[now][i]]=next[fail[now]][i]; q.push(next[now][i]); } } } } void solve() { for(int i=1;i<=n;i++) for(int j=0;j<L;j++) dp[i][j]=INF; dp[1][next[root][1]]=0;//开始时在1位置,所以节点不在自动机的root节点了 for(int i=1;i<=n;i++) { for(int j=0;j<L;j++) { if(dp[i][j]==INF) continue; for(int k=1;k<=n;k++) { int x=next[j][k]; if(ed[x]) continue; dp[k][x]=min(dp[k][x],dp[i][j]+dis(e[i],e[k])); } } } double ans=INF; for(int i=0;i<L;i++) ans=min(ans,dp [i]); if(ans==INF) puts("Can not be reached!"); else printf("%.2f\n",ans); } }; AC A; int main() { char str[10];int x,k; while(~scanf("%d%d",&n,&m)) { if(n+m==0) break; A.init(); REPF(i,1,n) scanf("%d%d",&e[i].x,&e[i].y); while(m--) { int l=0; scanf("%d",&k); for(int i=0;i<k;i++) { scanf("%d",&x); str[l++]=x+'0'; } str[l]='\0'; A.Insert(str); } A.Build_AC(); A.solve(); } return 0; } /* 3 1 1 1 2 1 3 1 2 1 2 */
相关文章推荐
- hdu - 4511 小明系列故事——女友的考验(AC自动机+DP)
- hdu 4511 小明系列故事——女友的考验(AC自动机+dp)
- 【HDU】4511 小明系列故事——女友的考验 (AC自动机+DP)
- HDU 4511 小明系列故事——女友的考验 (AC自动机+DP)
- HDU - 4511 小明系列故事――女友的考验(AC自动机+DP)
- HDU 4511 小明系列故事——女友的考验 (AC自动机+DP)
- HDU 4511 小明系列故事——女友的考验 (AC自动机 + dp)
- HDU 4511 小明系列故事——女友的考验 (AC自动机 + DP)
- HDU 4511 小明系列故事——女友的考验(AC自动机 + DP)
- hdu4511---小明系列故事——女友的考验(AC自动机+dp)
- hdu 4511 小明系列故事——女友的考验
- AC自动机 + 二维最短路 HDU 4511 小明系列故事――女友的考验
- hdu4511 小明系列故事——女友的考验(AC自动机+dp)
- HDU 4511 小明系列故事——女友的考验
- hdu 4511 小明系列故事——女友的考验
- HDU-4511 小明系列故事——女友的考验 floyd变种-标号递增最短路
- hdu 4511 小明系列故事——女友的考验
- hdu4511小明系列故事——女友的考验(ac自动机+最短路)
- HDU4511 小明系列故事——女友的考验(AC自动机 + DP)
- hdu-4501-小明系列故事——买年货-dp-java