Description
Input
Output
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
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <set>
#include <queue>
#include <cmath>
using namespace std;
const double inf = 1e20;
pair<int, int> p[100];
int n;
double dp[55][1000];
double dis(pair<int, int> a, pair<int, int> b) {
return sqrt((double)(1.0 * a.first - b.first) * (1.0 * a.first - b.first) + (double)(1.0 * a.second - b.second)*(1.0 * a.second - b.second));
}
struct Tie {
int nxt[1000][55], fail[1000], end[1000];
int root, cnt;
int newNode() {
for (int i = 1; i <= n; i++)
nxt[cnt][i] = -1;
end[cnt++] = 0;
return cnt - 1;
}
void init() {
cnt = 0;
root = newNode();
}
void insert(int a[], int len) {
int now = root;
for (int i = 0; i < len; i++) {
if (nxt[now][a[i]] == -1)
nxt[now][a[i]] = newNode();
now = nxt[now][a[i]];
}
end[now] = 1;
}
void build() {
queue<int> q;
fail[root] = root;
for (int i = 1; i <= n; i++) {
if (nxt[root][i] == -1)
nxt[root][i] = root;
else {
fail[nxt[root][i]] = root;
q.push(nxt[root][i]);
}
}
while (!q.empty()) {
int now = q.front();
q.pop();
end[now] |= end[fail[now]];
for (int i = 1; i <= n; i++) {
if (nxt[now][i] == -1)
nxt[now][i] = nxt[fail[now]][i];
else {
fail[nxt[now][i]] = nxt[fail[now]][i];
q.push(nxt[now][i]);
}
}
}
}
void solve() {
for (int i = 1; i <= n; i++)
for (int j = 0; j < cnt; j++)
dp[i][j] = inf;
dp[1][nxt[root][1]] = 0;
for (int i = 1; i < n; i++)
for (int j = 0; j < cnt; j++)
if (dp[i][j] < inf) {
for (int k = i+1; k <= n; k++) {
int cur = nxt[j][k];
if (end[cur]) continue;
dp[k][cur] = min(dp[k][cur], dp[i][j] + dis(p[i], p[k]));
}
}
double ans = inf;
for (int i = 0; i < cnt; i++)
if (dp[n][i] < inf)
ans = min(ans, dp[n][i]);
if (ans == inf)
printf("Can not be reached!\n");
else printf("%.2lf\n", ans);
}
} ac;
int a[10];
int main() {
int m;
while (scanf("%d%d", &n, &m) != EOF && n + m) {
for (int i = 1; i <= n; i++)
scanf("%d%d", &p[i].first, &p[i].second);
ac.init();
int k;
while (m--) {
scanf("%d", &k);
for (int i = 0; i < k; i++)
scanf("%d", &a[i]);
ac.insert(a, k);
}
ac.build();
ac.solve();
}
return 0;
}
HDU - 4511 小明系列故事――女友的考验(AC自动机+DP)
原文:http://blog.csdn.net/u011345136/article/details/40052181