链接
https://vjudge.net/problem/UVA-1399
题解
建立
T
r
i
e
Trie
Trie图
判断是否是
D
A
G
DAG
DAG
如果有环,无解
否则跑拓扑排序
倒着
d
p
dp
dp
记录决策
代码
#include <bits/stdc++.h>
#define maxn 50010
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
int n;
struct Graph
{
int etot, head[maxn], to[maxn*26], next[maxn*26], w[maxn*26], in_deg[maxn], N;
vector<int> list;
void clear()
{
int i;
list.clear();
for(i=1;i<=N;i++)head[i]=0, in_deg[i]=0;
for(i=1;i<=etot;i++)to[i]=next[i]=w[i]=0;
N=etot=0;
}
void adde(int a, int b, int c)
{
to[++etot]=b;w[etot]=c;next[etot]=head[a];head[a]=etot;
in_deg[b]++;
}
void topo()
{
queue<int> q;
int u, v;
for(int i=1;i<=N;i++)if(in_deg[i]==0)q.emplace(i);
while(!q.empty())
{
u=q.front(); q.pop();
list.emplace_back(u);
for(auto p=head[u];p;p=next[p])
{
in_deg[to[p]]--;
if(in_deg[to[p]]==0)
{
q.emplace(to[p]);
}
}
}
}
}G;
struct ACautomaton
{
int trie[maxn][30], tot, fail[maxn], tail[maxn];
void clear() //clear the arrays
{
for(int i=1;i<=tot;i++)cl(trie[i]), fail[i]=tail[i]=0;
tot=1;
}
int insert(int *r, int len) //insert a string into trie tree
{
auto pos=1;
for(auto i=1;i<=len;i++)
pos = trie[pos][r[i]] ? trie[pos][r[i]] : trie[pos][r[i]]=++tot;
tail[pos]++;
return pos;
}
void build() //build the aca
{
queue<int> q;
int u, v, f;
q.push(1);
while(!q.empty())
{
u=q.front(); q.pop();
for(auto i=1;i<=n;i++)
if(trie[u][i])
{
v=trie[u][i];
for(f=fail[u];f and !trie[f][i];f=fail[f]);
fail[v] = f ? trie[f][i] : 1;
tail[v]+=tail[fail[v]];
q.push(v);
}
}
}
int move(int pos, int c)
{
for(;pos and !trie[pos][c];pos=fail[pos]);
return pos ? trie[pos][c] : 1;
}
}aca;
int read(int x=0)
{
int c, f(1);
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
for(;isdigit(c);c=getchar())x=x*10+c-48;
return f*x;
}
int f[maxn], alpha[maxn];
void dp()
{
int i, j;
for(i=1;i<=G.N;i++)f[i]=alpha[i]=0;
for(auto it=G.list.rbegin();it!=G.list.rend();it++)
{
if(!aca.tail[*it])f[*it]=1;
else continue;
for(auto p=G.head[*it];p;p=G.next[p])
{
if(aca.tail[G.to[p]])continue;
if(f[*it]<f[G.to[p]]+1)
{
f[*it]=f[G.to[p]]+1;
alpha[*it]=G.w[p];
}
else if(f[*it]==f[G.to[p]]+1 and G.w[p]>alpha[*it])
{
alpha[*it]=G.w[p];
}
}
}
}
void display()
{
for(auto x=1;alpha[x];x=aca.move(x,alpha[x]))putchar(alpha[x]+'A'-1);
putchar(10);
}
char s[maxn];
int r[maxn];
int main()
{
int T(read()), m;
while(T--)
{
aca.clear();
G.clear();
//初始化自动机
n=read(), m=read();
for(auto i=1;i<=m;i++)
{
scanf("%s",s+1);
auto len=strlen(s+1);
for(auto i=1;i<=len;i++)r[i]=s[i]-'A'+1;
aca.insert(r,len);
}
aca.build();
//建图
G.N=aca.tot;
for(auto i=1;i<=aca.tot;i++)
{
if(aca.tail[i])continue;
for(auto alpha=1;alpha<=n;alpha++)
{
G.adde( i, aca.move(i,alpha), alpha);
}
}
//拓扑排序
G.topo();
if(G.list.size() != G.N) //存在环,无解
{
printf("No\n");
continue;
}
dp();
if(f[1]==1)
{
printf("No\n");
continue;
}
display();
}
return 0;
}