1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
| #include<bits/stdc++.h> using namespace std; typedef unsigned long long ll; #define pb push_back typedef pair <int,int> Pii; #define mp make_pair #define rep(i,a,b) for(int i=a,i##end=b;i<=i##end;++i) #define drep(i,a,b) for(int i=a,i##end=b;i>=i##end;--i) char IO; int rd(){ int s=0; while(!isdigit(IO=getchar())); do s=(s<<1)+(s<<3)+(IO^'0'); while(isdigit(IO=getchar())); return s; }
const int N=210,M=52; const ll INF=-1;
int n,m,k,c; typedef vector <int> V; int trie[M][2],fail[M],mk[M],cnt; void Ins(const V &S){ int now=0; for(int i:S) { int &nxt=trie[now][i]; if(!nxt) nxt=++cnt; now=nxt; } mk[now]=1; } void Build(){ static queue <int> que; rep(i,0,1) if(trie[0][i]) que.push(trie[0][i]); while(!que.empty()) { int u=que.front(); que.pop(); mk[u]|=mk[fail[u]]; rep(i,0,1){ int &v=trie[u][i]; if(v) que.push(v); (!v?v:fail[v])=trie[fail[u]][i]; } } mk[cnt+1]=1; rep(i,0,cnt) rep(j,0,1) if(mk[i] || mk[trie[i][j]]) trie[i][j]=cnt+1; }
V Read(){ V Res; rep(i,1,rd()) Res.pb(rd()); return Res; }
vector <Pii> G[N]; ll dis[N][M][M]; struct Node{ int u,s,t; ll d; bool operator < (const Node &__) const { return d>__.d; } }; priority_queue <Node> que; void Upd(int u,int s,int t,ll d){ if(mk[s]||mk[t]||dis[u][s][t]<=d) return; dis[u][s][t]=d,que.push((Node){u,s,t,d}); }
int main(){ c=n=rd()-1,m=rd(),k=rd(); ++c; rep(i,1,m) { int u=rd(); V w=Read(); int lst=n+1; rep(j,0,w.size()-1) { if(j==jend) G[lst].pb(mp(w[j],u)),G[w[j]].pb(mp(lst,u)); else G[lst].pb(mp(w[j],++c)),G[w[j]].pb(mp(lst,c)),lst=c; } } rep(i,1,k) Ins(Read()); Build(); memset(dis,255,sizeof dis); rep(i,0,cnt) if(!mk[i]) dis[n+1][i][i]=0; rep(u,0,1) rep(i,0,cnt) Upd(u,i,trie[i][u],1); while(!que.empty()) { int u=que.top().u,s=que.top().s,t=que.top().t; ll d=que.top().d; que.pop(); if(d>dis[u][s][t]) continue; for(auto i:G[u]) { int v=i.first,to=i.second; if(u<=n) { rep(i,0,cnt) if(dis[v][i][s]<INF) Upd(to,i,t,dis[v][i][s]+d); } else { rep(i,0,cnt) if(dis[v][t][i]<INF) Upd(to,s,i,d+dis[v][t][i]); } } } rep(i,2,n) { ll ans=-1; rep(j,0,cnt) if(!mk[j]) ans=min(ans,dis[i][0][j]); if(ans==INF) puts("YES"); else printf("NO %llu\n",ans); } }
|