This question is still relatively good to think of.
Start by setting up an AC automaton for all the non-possible schemes, and then run the shortest way.
First put xiaoming at (sta = 0,pos = 0), STA represents the number of points on the AC automaton, POS represents the number of coordinate points.
According to the POS enumeration where the next can be reached [pos+1,n], then STA moves on the automaton, and if a step causes the STA to be located in a labeled node, then this step is not possible.
#include <iostream> #include <time.h> #include <stdio.h> #include <string.h> #include < stdlib.h> #include <string> #include <map> #include <vector> #include <algorithm> #include <queue> #include <cmath> #define LL long long#define ULL unsigned long longusing namespace Std;const int maxs = 55,MAXN = 510;const int matn = 70;struct mat{int row,col; ULL Mat[matn][matn]; void Init (int r,int c,int val) {row = R,col = C; for (int i = 1;i <= row, ++i) for (int j = 1;j <= col; ++j) mat[i][j] = (i = = J val: 0); } Mat Multi (Mat c,ll MOD) {mat tmp; Tmp. Init (this->row,c.col,0); int i,j,k; for (k = 1;k <= this->col; ++k) for (i = 1;i <= tmp.row; ++i) for (j = 1;j <= tmp.col; ++J) Tmp.mat[i][j] + = (this->mat[i][k]*c.mat[k][j]); return TMP; } Mat Quick (LL n,ll MOD) {matRes,tmp = *this; Res. Init (row,col,1); while (n) {if (n&1) res = res. Multi (TMP,MOD); TMP = tmp. Multi (TMP,MOD); n >>= 1; } return res; } void Output () {cout<< "****************" <<endl; int i,j; for (i = 1;i <= row; ++i) {for (j = 1;j <= col; ++j) printf ("%3lld", Mat[i][j]); Puts (""); } cout<< "&&&&&&&&&&&&&" <<endl; }};struct trie{int NEXT[MAXS]; int fail; int flag;} st[maxn];queue<int> q;struct pos{int x, y;} pos[55];struct acautomaton{int top,root; int creat () {memset (st[top].next,-1,sizeof (St[top].next)); St[top].flag = 0; St[top].fail =-1; return top++; } void Init () {Top = 0; root = creat (); } Inline INT Calindex (int c) {return C; } void Insert (int *s) {int i = 0,TR = root,tmp; while (s[i]! =-1) {tmp = Calindex (s[i]); if (st[tr].next[tmp] = =-1) st[tr].next[tmp] = creat (); tr = st[tr].next[tmp],++i; } St[tr].flag = 1; } void Getfail () {st[root].fail =-1; Q.push (root); int f,t; while (q.empty () = = False) {f = Q.front (); Q.pop (); for (int i = 0; i < Maxs; ++i) {if (st[f].next[i]! =-1) {T = St[f].fail; while (t! =-1 && st[t].next[i] = =-1) t = st[t].fail; if (t = =-1) st[st[f].next[i]].fail = root; else St[st[f].next[i]].fail = St[t].next[i]; Q.push (St[f].next[i]); }}}} int Match (char *s) {int I, tr = root,tmp; int ans = 0; for (i = 0; s[i]! = ' + '; ++i) {if (S[i] < ' A ' | | ' Z ' < s[i]) {tr = root; Continue } tmp = Calindex (s[i]); while (tr! =-1 && st[tr].next[tmp] = =-1) tr = st[tr].fail; if (tr = =-1) {tr = root; Continue } tr = st[tr].next[tmp]; TMP = TR; while (tmp! = root && St[tmp].flag! =-1) {if (St[tmp].flag) ans++,st[ Tmp].flag =-1; }} return ans; }};int num[10];d ouble dis[510][55];d ouble val[55][55];struct q{int s,p;}; queue<q> que;double Cal (int p1,int P2) {if (P1 = = 0 && P2 = = 1) return 0; Pos p1 = Pos[p1]; Pos P2 = pos[p2]; return sqrt ((p1.x+0.0-p2.x) * (p1.x+0.0-p2.x) + (P1.Y+0.0-P2.Y) * (P1.Y+0.0-P2.Y) + 0.0);} int main () {int n,m; int i,k,j; Acautomaton AC; while (scanf ("%d%d", &n,&m) && (n| | m) {for (i = 1;i <= n; ++i) scanf ("%d%d", &pos[i].x,&pos[i].y); AC. Init (); while (m--) {scanf ("%d", &k); for (i = 0;i < K; ++i) scanf ("%d", &num[i]); NUM[K] =-1; AC. Insert (num); } AC. Getfail (); for (i = 1;i <= N, ++i) {for (j = 1;j <= n; ++j) val[i][j] = sqrt ((pos[i].x-pos[i].x ) * (pos[i].x-pos[i].x) + (POS[I].Y-POS[I].Y) * (POS[I].Y-POS[I].Y)); } for (i = 1;i <= n; ++i) val[i][0] = Val[0][i] = 0; for (i = 0;i < AC. Top; ++i) for (j = 1;j <= n; ++j) Dis[i][j] =-1; Dis[0][0] = 0; Que.push ((Q) {0,0}); Q f,t; while (que.empty () = = False) {f = Que.front (); Que.pop (); for (i = f.p+1;i <= (f.p = = 0? 1:n); ++i) {int tr = F.S; while (tr! =-1) {if (st[tr].next[i]! =-1 && st[st[tr].next[i]].flag! = 0) Break tr = St[tr].fail; } if (tr! =-1) continue; tr = F.S; while (tr! =-1) {if (st[tr].next[i]! =-1) break; tr = St[tr].fail; } if (tr = =-1) tr = 0; else tr = st[tr].next[i]; if (dis[tr][i] = = 1 | | dis[tr][i] > DIS[F.S][F.P] + Cal (f.p,i)) {Dis[tr][i] = dis[f. S][F.P] + Cal (f.p,i); Que.push ((Q) {tr,i}); }}} Double Min =-1; for (i = 0;i < AC.Top; ++i) {if (Dis[i][n]! =-1) {if (Min = =-1) Min = Dis[i][n]; else min = min (min,dis[i][n]); }} if (Min = =-1) printf ("Can not is reached!\n"); else printf ("%.2lf\n", Min); } return 0;}
AC automata + two-dimensional shortest path HDU 4511 Xiao Ming series Story--the test of the girlfriend