bzoj 1195 [HNOI2006] shortest bus string bfs-like voltage shortest AC automaton

LINK: shortest female string

Seeking the problem of the mother string. Not suitable for SAM.

You can simplify the problem first and consider that the n strings given do not have an inclusion relationship.

Then there are only two strings that can be spliced ​​together to indicate that another string or the suffix of a certain string can be used as a prefix of another string.

The actual situation may be more complicated.

Observing the above two situations is easy for AC automata to solve similar problems.

When running on an AC automaton, you can borrow the suffix of another string as your own prefix.

Considering the establishment of an AC automaton, we require a path to make all the termination nodes on the AC automaton pass through.

Of course, there are also special cases where the node with the termination node as the fail or the node with the node as the fail is passed through.

Consider how to find the shortest path.

It can be found that this is a short-circuit problem. Run the shortest route as a layered graph.

The above two cases can be satisfied because they are running on the trie graph of the AC automaton.

Consider the lexicographic order to select the node with the smallest lexicographic order each time.

Note that it is necessary to preprocess the s [x] array to represent the set of all termination nodes represented by the node x. Note that the s of the fail pointer can be passed over.

const int MAXN=610,maxn=1<<12;
int n,cnt,maxx;
char a[13][MAXN],b[MAXN],ans[MAXN];
int s[MAXN],q[1500010],vis[MAXN][maxn],pre[MAXN][maxn],w[1500010];
struct wy{int ch[26];int fail;}t[MAXN];

inline void insert(int x)
{
	int len=strlen(a[x]+1);
	int p=0;
	rep(1,len,i)
	{
		int w=a[x][i]-'A';
		if(!t[p].ch[w])t[p].ch[w]=++cnt;
		p=t[p].ch[w];b[p]=a[x][i];
	}
	s[p]=s[p]|(1<<(x-1));
}

inline void get_fail()
{
	int l=0,r=0;
	rep(0,25,i)if(t[0].ch[i])q[++r]=t[0].ch[i];
	while(++l<=r)
	{
		int x=q[l];
		rep(0,25,i)
		{
			int tn=t[x].ch[i];
			if(tn)fail(tn)=t[fail(x)].ch[i],s[tn]|=s[t[fail(x)].ch[i]],q[++r]=tn;
			else t[x].ch[i]=t[fail(x)].ch[i];
		}
	}
}

inline void bfs()
{
	int l=0,r=0;q[++r]=0;
	vis[0][0]=0;w[r]=0;
	while(++l<=r)
	{
		int x=q[l];
		int xx=w[l];
		rep(0,25,i)
		{
			int tn=t[x].ch[i];
			if(tn)
			{
				int ss=s[tn]|xx;
				if(vis[tn][ss]==-1)
				{
					pre[tn][ss]=l;
					vis[tn][ss]=vis[x][xx]+1;
					q[++r]=tn;w[r]=ss;
					if(ss==maxx)
					{
						int w1=tn,w2=ss;
						while(vis[tn][ss])
						{
							ans[vis[tn][ss]]=b[w1];
							--vis[tn][ss];
							int s1=q[pre[w1][w2]];
							int s2=w[pre[w1][w2]];
							w1=s1;w2=s2;
						}
						printf("%s",ans+1);
						return;
					}
				}
			}
		}
	}
}

int main()
{
	freopen("1.in","r",stdin);
	gt(n);maxx=(1<<n)-1;
	rep(1,n,i)gc(a[i]),insert(i);
	get_fail();
	memset(vis,-1,sizeof(vis));
	bfs();return 0;
}

Guess you like

Origin www.cnblogs.com/chdy/p/12723043.html