其实就是求1到n的最短路,且不包含特定子串,可以利用ac自动机构建不可到达的状态我们可以设dp【i】【j】来表示到达i节点时候位于自动机j节点的花费
ACcode:
#include <bits/stdc++.h>
const double inf=1e20;
using namespace std;
typedef pair<double,double> D;
D data[55];
double dp[55][505];
int in[15],N,m;
struct Aho{
struct state{
int next[55];
int fail,cnt;
}s[505];
int size;
queue<int>q;
void init(){
while(q.size())q.pop();
for(int i=0;i<505;++i){
memset(s[i].next,-1,sizeof(s[i].next));
s[i].cnt=s[i].fail=0;
}
size=1;
}
void insert(int n){
int now=0;
for(int i=0;i<n;++i){
if(s[now].next[in[i]]==-1)
s[now].next[in[i]]=size++;
now=s[now].next[in[i]];
}
s[now].cnt=1;
}
double dis(D& a,D& b){
return sqrt((a.first-b.first)*(a.first-b.first)+(a.second-b.second)*(a.second-b.second));
}
void build(){
s[0].fail=0;
for(int i=0;i<55;++i)
if(s[0].next[i]==-1)
s[0].next[i]=0;
else {
s[s[0].next[i]].fail=0;
q.push(s[0].next[i]);
}
while(q.size()){
int u=q.front();
q.pop();
for(int i=0;i<55;++i)
if(s[u].next[i]==-1)
s[u].next[i]=s[s[u].fail].next[i];
else {
s[s[u].next[i]].fail=s[s[u].fail].next[i];
s[u].cnt|=s[s[u].fail].cnt;
q.push(s[u].next[i]);
}
}
fill(&dp[0][0],&dp[54][54-1],inf);;
dp[0][s[0].next[0]]=0;
for(int i=0;i<N-1;++i)
for(int j=0;j<size;++j){
if(dp[i][j]==inf)continue;
for(int k=i+1;k<N;++k){
if(s[s[j].next[k]].cnt)continue;
dp[k][s[j].next[k]]=min(dp[k][s[j].next[k]],dp[i][j]+dis(data[i],data[k]));
}
}
double ans=inf;
for(int i=0;i<size;++i)ans=min(ans,dp[N-1][i]);
if(ans==inf)printf("Can not be reached!\n");
else printf("%.2f\n",ans);
}
}aho;
int main(){
while(cin>>N>>m){
if(N==0&&m==0)break;
aho.init();
for(int i=0;i<N;++i)scanf("%lf%lf",&data[i].first,&data[i].second);
for(int i=0;i<m;++i){
int k;
scanf("%d",&k);
for(int j=0;j<k;++j){
scanf("%d",&in[j]);
in[j]--;
}
aho.insert(k);
}
aho.build();
}
return 0;
}
/*
6 2
1 3
2 4
5 7
4 3
2 8
7 8
3
1 3 4
2
5 6
*/