题意:给定一些宏以及宏的定义,问指定宏展开后是否是某个字符串的匹配串。
比如
START = FIRST + SECND
• FIRST = D + E
• SECND = F + E
• D = good
• E = times
• F = bad
START的展开为goodtimesbadtimesgoodtimesbadtimes,给定一个询问。debatedebate,这个串在goodtimesbadtimesgoodtimesbadtimes中顺序出现。。。。

给定的宏只有两种方式 一种是 宏 = 宏 + 宏 另一种是 宏 = 单词
这样我们可以建出一个单向无环图(题目保证无环),那么对于每个节点,可以求这个节点对于给的串第i个字符开始最多能匹配的个数。依次往上推即可~~
代码:

#include <iostream>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
const int MAXN = 10000;
char strs[MAXN][20];
map <string,int> m;
map <string,int> ::iterator it;
char tmp[3000];
char t1[10],t2[10],t3[10];
struct Edge {
int to,next;
Edge(){}
Edge(int _to,int _next):to(_to),next(_next){}
}e[20000];
int head[MAXN],tot,ctot;
void init(){
//for(int i=0;i<=2000;i++)head[i]=-1;
memset(head,-1,sizeof(head));
ctot=tot=0;
}
void AddEdge(int u,int v){
e[tot]=Edge(v,head[u]);
head[u]=tot++;
//while(ctot>2000)puts("fuck");
}
int Tj,len;
int has[MAXN],chas[MAXN];
int dp[MAXN][2010];
void dfs(int u){
//if(Tj==len)return;
has[u]=1;
for(int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(has[v])continue;
dfs(v);
}
int ct=0;
if(chas[u]){
int len1=strlen(strs[u]);
for(int j=0;j<len;j++){
int cnt=0;
for(int i=0;i<len1;i++){
if(j+cnt<len&&tmp[j+cnt]==strs[u][i])++cnt;
//if(strs[u][i]==tmp[Tj])++Tj;
}
dp[u][j]=cnt;
}
dp[u][len]=0;
}
else
for(int i=head[u];~i;i=e[i].next){
int v=e[i].to;
++ct;
if(ct==1){
for(int j=0;j<=len;j++)dp[u][j]=dp[v][j];
}
else {
for(int j=0;j<len;j++)dp[u][j]+=dp[v][j+dp[u][j]];
}
}
}
int main(){
int T,n;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
init();
m.clear();
getchar();
memset(chas,0,sizeof(chas));
for(int i=0;i<n;i++){
fgets(tmp,sizeof(tmp),stdin);
int flag=0;
for(int j=0;tmp[j];j++)if(tmp[j]=='+'){flag=1;break;}
int n1,n2,n3;
if(flag){
sscanf(tmp," %s = %s + %s",t1,t2,t3);
it=m.find(t1);
if(it==m.end()){
strcpy(strs[ctot],t1);
m.insert(pair<string,int>(t1,ctot++));
n1=ctot-1;
}
else n1=m[t1];
it=m.find(t2);
if(it==m.end()){
strcpy(strs[ctot],t2);
m.insert(pair<string,int>(t2,ctot++));
n2=ctot-1;
}
else n2=m[t2];
it=m.find(t3);
if(it==m.end()){
strcpy(strs[ctot],t3);
m.insert(pair<string,int>(t3,ctot++));
n3=ctot-1;
}
else n3=m[t3];
AddEdge(n1,n3);
AddEdge(n1,n2);
}
else {
sscanf(tmp," %s = %s",t1,t2);
it=m.find(t1);
if(it==m.end()){
strcpy(strs[ctot],t1);
m.insert(pair<string,int>(t1,ctot++));
n1=ctot-1;
}
else n1=m[t1];
it=m.find(t2);
if(it==m.end()){
strcpy(strs[ctot],t2);
m.insert(pair<string,int>(t2,ctot++));
n2=ctot-1;
}
else n2=m[t2];
AddEdge(n1,n2);
chas[n2]=1;
}
}
scanf("%s",tmp);
int nn=m[tmp];
it=m.find(tmp);
scanf("%s",tmp);
if(it==m.end()){
puts("NO");
continue;
}
len=strlen(tmp);
memset(has,0,sizeof(has));
dfs(nn);
if(dp[nn][0]==len)puts("YES");
else puts("NO");
}
return 0;
}