Description
Tom is going to watch a movie with his girlfriend after the winter vacation. On this day, my girlfriend wanted to give Xiao Ming a test. While Xiao Ming was preparing to leave, she told him that she was waiting for him at the cinema. The route that James came over must satisfy the given rules:
1. Assume that James is at and his girlfriend is at, then there is a N-2 between them, james can only go to a location larger than the number of the current vertex each time he walks;
2. When James came, he could not pass through some places in a certain order. For example, if your girlfriend tells James that the path cannot pass through 1-> 2-> 3, the path that James traveled must not include 1-> 2-> 3, but 1-> 3 or 1-> 2 are all possible. There may be multiple restricted paths.
This gave James a headache. Now he has handed over the problem to you.
In particular, if the three vertices 1 2 3 are collocated, but James continues from 1 to 3 and then from 3, in this case, James is not considered to have passed this point.
Now, James wants to meet his girlfriend as soon as possible and does not want to break the rules of his girlfriend. Can you help James solve this problem?
Input
The input contains multiple groups of samples. Each group contains two integers, N and M. N indicates that there are N points. James is at and his girlfriend is, M indicates that James's girlfriend has m requirements;
In the next n rows, enter two integers x and y (both X and Y are in the int range) to represent the positions of the N points (the number of the points ranges from 1 to n );
Then there are m requirements. Each request requires 2 rows. The first row is a K, which indicates that this requirement is related to k vertices, and then the k vertices in sequence are numbered, it means james cannot go through K1-> k2-> K3 ...... -> The path of the ki sequence;
When N and m are equal to 0, the input ends.
[Technical Specification]
2 <= n <= 50
1 <= m <= 100
2 <= k <= 5
Output
For each sample, if there is a shortest path that meets the requirements, please output this shortest path and keep two decimal places in the result; otherwise, please output "can not be reached !" (Quotes are not output ).
Sample Input
3 11 12 13 121 22 10 01 12 1 25 30 05 31 21 225 2131 2 32 4 521 50 0
Sample output
2.00Can not be reached!21.65
Train of Thought: Set DP [I] [J] to represent the smallest step number from the point I to the state of the automatic machine to J. Note that we construct an automatic machine based on an invalid path, therefore, we cannot reach the end of a certain path. Based on this, we can record our termination conditions.
#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 James series story-girlfriend's test (AC automation + dp)