【bzoj3012】[Usaco2012 Dec]First! trie+拓扑排序
2015-11-26 15:00
369 查看
一开始没有想到暴力就可以,trie的题目复杂度都非常搞笑呀,考虑每一个串如果有一个串是它的前缀,则肯定不行,否则每次从这个字母,向同一个父亲的其他字母连边,如果最后出现环,就是出现矛盾,于是拓扑排序判环就可以了。
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> #define maxn 300010 using namespace std; int ch[maxn][26]; bool tag[maxn]; char s[30010][310]; int q[26],head[26],next[2010],to[2010],d[26]; int a[26][26]; int ans[30010]; int n,m,tot,num,cnt; bool w; void insert(char s[]) { int n=strlen(s+1),x=0; for (int i=1;i<=n;i++) { if (!ch[x][s[i]-'a']) ch[x][s[i]-'a']=++tot; x=ch[x][s[i]-'a']; } tag[x]=1; } void addedge(int x,int y) { if (a[x][y]) return; num++;to[num]=y;next[num]=head[x];head[x]=num; d[y]++;a[x][y]=1; } void query(char s[]) { int n=strlen(s+1),x=0; for (int i=1;i<=n;i++) { if (tag[x]) {w=1;return;} for (int j=0;j<26;j++) if (j!=s[i]-'a' && ch[x][j]) addedge(s[i]-'a',j); x=ch[x][s[i]-'a']; } } bool check() { int l=0,r=0; for (int i=0;i<26;i++) if (!d[i]) q[++r]=i; while (l<r) { int x=q[++l]; for (int p=head[x];p;p=next[p]) if (d[to[p]]) { d[to[p]]--; if (!d[to[p]]) q[++r]=to[p]; } } return (r==26); } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%s",s[i]+1); insert(s[i]); } for (int i=1;i<=n;i++) { num=0;w=0; memset(head,0,sizeof(head)); memset(d,0,sizeof(d)); memset(a,0,sizeof(a)); query(s[i]); if (!w && check()) ans[++cnt]=i; } printf("%d\n",cnt); for (int i=1;i<=cnt;i++) printf("%s\n",s[ans[i]]+1); return 0; }
相关文章推荐
- 图片下载(不使用开源框架)
- iOS 保存图片到自己的App的一种思路
- Bootstrap 页面标题(Page Header)
- MongoDB入门实践
- 自定义事件分发,执行耗时操作服务
- opencv2.4.9中K-means算法理解
- winform登录时载入验证码,并且点击可刷新
- declspec(dllexport)和declspec(dllexport)的实际应用
- 无线网卡的Master,Managed,ad-hoc,monitor模式
- UI_界面传值方式
- C++primer plus第六版课后编程练习答案5.7
- 一次 JVM 调优的笔记
- Caffe中learning rate 和 weight decay 的理解
- 容斥原理-shuoj—小明系列之高中时光
- PHP 解析JSON数组
- 单个listView展示多类型Item出现混乱显示的问题
- JAVA【设计模式】—— 总览导图
- 计算机网络---基础题目汇总二
- ListView 中使用Button中不响应OnItemClickListener事件
- 求复数的对数