HDU4511 AC自动机+dijkstra
Posted Dirge
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU4511 AC自动机+dijkstra相关的知识,希望对你有一定的参考价值。
题意:
Description
终于放寒假了,小明要和女朋友一起去看电影。这天,女朋友想给小明一个考验,在小明正准备出发的时候,女朋友告诉他,她在电影院等他,小明过来的路线必须满足给定的规则:
1、假设小明在的位置是1号点,女朋友在的位置是n号点,则他们之间有n-2个点可以走,小明每次走的时候只能走到比当前所在点编号大的位置;
2、小明来的时候不能按一定的顺序经过某些地方。比如,如果女朋友告诉小明不能经过1 -> 2 -> 3,那么就要求小明来的时候走过的路径不能包含有1 -> 2 -> 3这部分,但是1 -> 3 或者1 -> 2都是可以的,这样的限制路径可能有多条。
这让小明非常头痛,现在他把问题交给了你。
特别说明,如果1 2 3这三个点共线,但是小明是直接从1到3然后再从3继续,那么此种情况是不认为小明经过了2这个点的。
现在,小明即想走最短的路尽快见到女朋友,又不想打破女朋友的规定,你能帮助小明解决这个问题吗?
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
接下来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!” (引号不用输出)。
1 #include <bits/stdc++.h> 2 #include <cstdio> 3 #include <iostream> 4 #include <algorithm> 5 #define ll long long 6 #define lson l, m, rt<<1 7 #define rson m+1, r, rt<<1|1 8 #define st first 9 #define nd second 10 #define mp make_pair 11 #define pii pair<int, int> 12 #define pdi pair<double, int> 13 #define gg puts("gg"); 14 //#define local 15 //#define out1 16 using namespace std; 17 const int N = 6e4+10; 18 const int inf = 0x3f3f3f3f; 19 int id(int c){ 20 return c-1; 21 } 22 struct Tire{ 23 int nex[N][50], fail[N],end[N], ch[N]; 24 int root, L, tot; 25 int newnode(){ 26 memset(nex[L], -1, sizeof(nex[L])); 27 end[L] = 0; 28 ch[L] = 0; 29 return L++; 30 } 31 void init(){ 32 L = tot = 0; 33 root = newnode(); 34 } 35 void insert(int* s, int len, int tag){ 36 int now = root; 37 for(int i = 0; i < len; i++){ 38 int p = id(s[i]); 39 if(nex[now][p] == -1) 40 nex[now][p] = newnode(); 41 now = nex[now][p]; 42 ch[now] = p; 43 } 44 end[now] = tag; 45 } 46 void build(){ 47 queue<int> Q; 48 fail[root] = root; 49 for(int i = 0; i < 50; i++){ 50 int& u = nex[root][i]; 51 if(u == -1) 52 u = root; 53 else{ 54 fail[u] = root; 55 Q.push(u); 56 } 57 } 58 while(!Q.empty()){ 59 int now = Q.front(); 60 Q.pop(); 61 for(int i = 0; i < 50; i++){ 62 int& u = nex[now][i]; 63 if(u == -1) 64 u = nex[ fail[now] ][i]; 65 else{ 66 fail[u] = nex[ fail[now] ][i]; 67 end[u] |= end[ fail[u] ]; 68 Q.push(u); 69 } 70 } 71 } 72 } 73 }; 74 Tire ac; 75 ll x[55], y[55]; 76 double w[55][55]; 77 int s[10]; 78 vector< pdi > ve[505]; 79 priority_queue< pdi, vector< pdi >, greater< pdi > >Q; 80 double d[505]; 81 double dijkstra(int S){ 82 int i, x; 83 for(i = 0; i < 505; i++) d[i] = 1e30; 84 Q.push(mp(d[S]=0,S)); 85 while(!Q.empty()){ 86 pdi t = Q.top(); Q.pop(); 87 if(d[x = t.nd] < t.st) continue; 88 for(i = 0; i < ve[x].size(); i++) 89 if(d[x]+ve[x][i].st < d[ve[x][i].nd]){ 90 d[ve[x][i].nd] = d[x]+ve[x][i].st; 91 Q.push( mp(d[ve[x][i].nd], ve[x][i].nd) ); 92 } 93 } 94 } 95 int main(){ 96 int n, m, ca = 1; 97 while(~scanf("%d%d", &n, &m), n+m){ 98 for(int i = 1; i <= n; i++) 99 scanf("%lld%lld", x+i, y+i); 100 for(int i = 0; i <= n; i++) 101 for(int j = 0; j <= n; j++) w[i][j] = 1e30; 102 for(int i = 1; i <= n; i++) 103 for(int j = i+1; j <= n; j++) 104 w[i][j] = sqrt( 1.0*(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]) ); 105 106 ac.init(); 107 for(int i = 1; i <= n; i++){ 108 s[0] = i; 109 ac.insert(s, 1, 0); 110 } 111 112 for(int i = 1; i <= m; i++){ 113 int k; scanf("%d", &k); 114 for(int j = 0; j < k; j++) 115 scanf("%d", s+j); 116 ac.insert(s, k, 1); 117 } 118 ac.build(); 119 for(int i = 0; i < ac.L; i++) ve[i].clear(); 120 for(int i = 1; i < ac.L; i++){ 121 int u = ac.ch[i]+1; 122 for(int j = u+1; j <= n; j++) { 123 int to = ac.nex[i][id(j)]; 124 if(!ac.end[to]) ve[i].push_back( mp(w[u][j], to) ); 125 } 126 } 127 128 dijkstra(ac.nex[0][id(1)]); 129 double ans = 1e30; 130 for(int i = 1; i < ac.L; i++){ 131 if(ac.ch[i] == id(n)) 132 ans = min(ans, d[i]); 133 } 134 if(ans < 1e25) 135 printf("%.2f\n", ans); 136 else 137 puts("Can not be reached!"); 138 } 139 return 0; 140 }
后记:发现debug能力实在太弱了...调半天没看出来哪错了...代码能力不够啊!!!
以上是关于HDU4511 AC自动机+dijkstra的主要内容,如果未能解决你的问题,请参考以下文章
HDU 4511 小明系列故事——女友的考验 (AC自动机+DP)
HDU 4511 小明系列故事——女友的考验 (AC自动机 + DP)题解