洛谷.3065.第一!First!(Trie 拓扑)

题目链接

\(Description\)

给出n个字符串,问重定义英文字符的顺序(即字典序),有哪些单词可能排在第一

\(Solution\)

一个单词想要排在第一,首先是没有其它字符串是它的前缀。那么建一棵Trie树
其次,它字符的优先级要比和它有着相同前缀的要高。
也就是说,对于同一个父节点下,这个儿子的优先级要比其它兄弟要高
那么我们就连一条边,表示优先级高低。最后拓扑,如果有环,则不行
判断一个字符串只需在Trie树上边走边加边即可。如果它有子串,显然不行。

/*
发现对于拓扑理解有问题...
对于本题一对(u,v)只能建一条边,因为是大小关系 
最后入队过的某个元素一定不会在入队 

小数组尤其是要经常memset的一定不要开大!

c_str()是Borland封装的String类中的一个函数,它返回当前字符串的首字符地址,类型为constchar* 
*/
#include
#include
#include
const int N=3e5+5,M=3e4+5,S=27;

int n,tot,dgr[S],son[N][S],q[S],Enum,H[S],to[S*S],nxt[S*S];
bool vis[N],mrk[M],lnk[S][S];
std::string str[M];
char tmp[10005];

inline void AddEdge(int u,int v)
{
    to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
}
//void Insert(char *s)
void Insert(std::string s)//faster
//直接用全局的tmp略快一点 
{
//  int l=strlen(s),id,u=0;
    int l=s.size(),id,u=0;
    for(int i=0;i

转载于:https://www.cnblogs.com/SovietPower/p/8435056.html

你可能感兴趣的:(洛谷.3065.第一!First!(Trie 拓扑))