First!(ZJNU 2832)
题目大意
你有个字符串,现在你可以改变字典序的规则(改变字母间大小关系),使得某字符串成为字典序最小的字符串,问字符串中哪些可以成为字典序最小的字符串。
思路
由于我们想让某字符串字典序最小,那么就一定能得到字母与字母间的大小关系,而且如果这些关系没有冲突,那么就说明是能满足字典序最小的。对于这样的关系,我们可以用单向边来表示,然后冲突就说明有环,可以用拓扑或来处理。但是由于的范围,我们不可能对所有的字符串两两比较,于是我们考虑用树。我们可以先把所有的字符串都插到树中,然后再拿每一个字符串放到树中比较,就能很快得到字母间的关系,然后通过拓扑就能轻松解决。
代码
#include<bits/stdc++.h> using namespace std; int trie[500005][30]; int ed[500005]; int k=1; int edge[30][30]; void insert(string w) { int len=(int)w.size(); int p=0; for(int i=0;i<len;i++) { int c=w[i]-'a'; if(!trie[p][c]) trie[p][c]=k++; p=trie[p][c]; } ed[p]=1; } int search(string s) { int len=(int)s.size(); int p=0; int in[30]={0}; int cc=26; for(int i=0;i<len;i++) { if(ed[p])return 0; int c=s[i]-'a'; for(int j=0;j<26;j++)if(j!=c&&trie[p][j]) { if(!edge[c][j])in[j]++; edge[c][j]=1; } p=trie[p][c]; } queue<int>q; for(int i=0;i<26;i++)if(in[i]==0)q.push(i); while(!q.empty()) { int d=q.front(); cc--; q.pop(); for(int i=0;i<26;i++) { if(edge[d][i]) { in[i]--; if(in[i]==0)q.push(i); } } } if(cc)return 0; return 1; } string s[50005]; int cnt=0; int vis[50005]; int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { cin>>s[i]; insert(s[i]); } for(int i=1;i<=n;i++) { for(int j=0;j<26;j++) for(int kd=0;kd<26;kd++) edge[j][kd]=0; vis[i]=search(s[i]); if(vis[i])cnt++; } printf("%d\n",cnt); for(int i=1;i<=n;i++) if(vis[i])cout<<s[i]<<endl; return 0; }
__EOF__

本文作者:Jerry-Black
本文链接:https://www.cnblogs.com/Jerry-Black/p/16459658.html
关于博主:小蒟蒻一只( ̄^ ̄)ゞ
版权声明:转载请注明来源哟~ QAQ
声援博主:UP UP UP !!!
本文链接:https://www.cnblogs.com/Jerry-Black/p/16459658.html
关于博主:小蒟蒻一只( ̄^ ̄)ゞ
版权声明:转载请注明来源哟~ QAQ
声援博主:UP UP UP !!!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)