题意:自己看题目,中文体面。
题解:
把所有不能走的路径放入AC自动机中。
然后DP【i】【j】表示走到 i 这个点,且位于AC自动机 j 这个节点最短距离
然后直接DP即可。注意一点会爆int
1 #include <set> 2 #include <map> 3 #include <stack> 4 #include <queue> 5 #include <cmath> 6 #include <ctime> 7 #include <cstdio> 8 #include <string> 9 #include <vector> 10 #include <cstring> 11 #include <iostream> 12 #include <algorithm> 13 #include <unordered_map> 14 15 #define pi acos(-1.0) 16 #define eps 1e-9 17 #define fi first 18 #define se second 19 #define rtl rt<<1 20 #define rtr rt<<1|1 21 #define bug printf("****** ") 22 #define mem(a, b) memset(a,b,sizeof(a)) 23 #define name2str(x) #x 24 #define fuck(x) cout<<#x" = "<<x<<endl 25 #define sfi(a) scanf("%d", &a) 26 #define sffi(a, b) scanf("%d %d", &a, &b) 27 #define sfffi(a, b, c) scanf("%d %d %d", &a, &b, &c) 28 #define sffffi(a, b, c, d) scanf("%d %d %d %d", &a, &b, &c, &d) 29 #define sfL(a) scanf("%lld", &a) 30 #define sffL(a, b) scanf("%lld %lld", &a, &b) 31 #define sfffL(a, b, c) scanf("%lld %lld %lld", &a, &b, &c) 32 #define sffffL(a, b, c, d) scanf("%lld %lld %lld %lld", &a, &b, &c, &d) 33 #define sfs(a) scanf("%s", a) 34 #define sffs(a, b) scanf("%s %s", a, b) 35 #define sfffs(a, b, c) scanf("%s %s %s", a, b, c) 36 #define sffffs(a, b, c, d) scanf("%s %s %s %s", a, b,c, d) 37 #define FIN freopen("../in.txt","r",stdin) 38 #define gcd(a, b) __gcd(a,b) 39 #define lowbit(x) x&-x 40 #define IO iOS::sync_with_stdio(false) 41 42 43 using namespace std; 44 typedef long long LL; 45 typedef unsigned long long ULL; 46 const ULL seed = 13331; 47 const LL INFLL = 0x3f3f3f3f3f3f3f3fLL; 48 const int maxn = 1e6 + 7; 49 const int maxm = 8e6 + 10; 50 const int INF = 0x3f3f3f3f; 51 const int mod = 1e9 + 7; 52 int n, m, k, x[maxn], y[maxn], buf[105]; 53 54 double cal(int id1, int id2) { 55 return sqrt((1.0 * x[id1] - x[id2]) * (1.0 * x[id1] - x[id2]) + (1.0 * y[id1] - y[id2]) * (1.0 * y[id1] - y[id2])); 56 } 57 58 59 struct Aho_Corasick { 60 int next[510][52], fail[510], End[510]; 61 int root, cnt; 62 63 int newnode() { 64 for (int i = 0; i < 52; i++) next[cnt][i] = -1; 65 End[cnt++] = 0; 66 return cnt - 1; 67 } 68 69 void init() { 70 cnt = 0; 71 root = newnode(); 72 } 73 74 void insert(int len) { 75 int now = root; 76 for (int i = 0; i < len; i++) { 77 if (next[now][buf[i]] == -1) next[now][buf[i]] = newnode(); 78 now = next[now][buf[i]]; 79 } 80 End[now]++; 81 } 82 83 void build() { 84 queue<int> Q; 85 fail[root] = root; 86 for (int i = 0; i < 52; i++) 87 if (next[root][i] == -1) next[root][i] = root; 88 else { 89 fail[next[root][i]] = root; 90 Q.push(next[root][i]); 91 } 92 while (!Q.empty()) { 93 int now = Q.front(); 94 Q.pop(); 95 if (End[fail[now]]) End[now] = 1; 96 for (int i = 0; i < 52; i++) 97 if (next[now][i] == -1) next[now][i] = next[fail[now]][i]; 98 else { 99 fail[next[now][i]] = next[fail[now]][i]; 100 Q.push(next[now][i]); 101 } 102 } 103 } 104 105 double dp[52][510]; 106 107 void solve() { 108 for (int i = 0; i <= n; ++i) 109 for (int j = 0; j < cnt; ++j) 110 dp[i][j] = INFLL; 111 dp[1][next[root][1]] = 0; 112 for (int i = 1; i <= n; ++i) { 113 for (int j = 0; j < cnt; ++j) { 114 if (dp[i][j] == INFLL) continue; 115 for (int k = i + 1; k <= n; ++k) { 116 int idx = next[j][k]; 117 if (End[idx]) continue; 118 dp[k][idx] = min(dp[k][idx], dp[i][j] + cal(i, k)); 119 } 120 } 121 } 122 double ans = INFLL; 123 for (int i = 0; i < cnt; ++i) ans = min(ans, dp[n][i]); 124 if (ans == INFLL) printf("Can not be reached! "); 125 else printf("%.2f ", ans); 126 } 127 128 void debug() { 129 for (int i = 0; i < cnt; i++) { 130 printf("id = %3d,fail = %3d,end = %3d,chi = [", i, fail[i], End[i]); 131 for (int j = 0; j < 26; j++) printf("%2d", next[i][j]); 132 printf("] "); 133 } 134 } 135 } ac; 136 137 int main() { 138 // FIN; 139 while (~sffi(n, m)) { 140 if (n == 0 && m == 0) break; 141 for (int i = 1; i <= n; ++i) sffi(x[i], y[i]); 142 ac.init(); 143 for (int i = 0; i < m; ++i) { 144 sfi(k); 145 for (int j = 0; j < k; ++j) sfi(buf[j]); 146 ac.insert(k); 147 } 148 ac.build(); 149 ac.solve(); 150 } 151 return 0; 152 }