zoukankan      html  css  js  c++  java
  • Luogu P3065 [USACO12DEC]第一!First!【字典树/拓扑排序】By cellur925

    题意:给你许多字符串,你可以改变字母序大小,问有哪些字符串可能成为字典序最小的字符串。

    我们考虑把这些字符串都塞到(trie)树上。之后检索每一个字符串的时候,我们看和他同一层的地方是否有字符,如果有,我们就从他到同层字符连一条有向边,因为只有同层字符妨碍他可能会成为第一。之后进行拓扑排序,检查这种情况是否可以存在即可。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<queue>
    
    using namespace std;
    
    int n,len,ans,tot,cnt;
    int trie[300900][130],op[30090],head[100],du[100];
    bool end[300090];
    string tmp;
    string dic[30090];
    struct node{
    	int to,next;
    }edge[1000];
    
    void insert()
    {
    	int p=0;
    	for(int i=0;i<len;i++)
    	{
    		int qwq=tmp[i]-'a';
    		if(!trie[p][qwq]) trie[p][qwq]=++tot;
    		p=trie[p][qwq];
    	}
    	end[p]=1;
    }
    
    void add(int x,int y)
    {
    	edge[++cnt].to=y;
    	edge[cnt].next=head[x];
    	head[x]=cnt;du[y]++;
    }
    
    bool work()
    {
    	int p=0;
    	for(int i=0;i<len;i++)
    	{
    		int qwq=tmp[i]-'a';
    		if(end[p]) return 0;
    		for(int j=0;j<26;j++)
    			if(trie[p][j]&&qwq!=j) add(qwq,j);
    		p=trie[p][qwq];
    	}
    	return 1;
    }
    
    bool topsort()
    {
    	queue<int>q;
    	for(int i=0;i<26;i++) 
    		if(du[i]==0) q.push(i);
    	while(!q.empty())
    	{
    		int u=q.front();q.pop();
    		for(int i=head[u];i;i=edge[i].next)
    		{
    			int v=edge[i].to;
    			if(--du[v]==0) q.push(v);
    		}
    	}
    	for(int i=0;i<26;i++)
    		if(du[i]) return 0;
    	return 1;
    }
    
    void clear()
    {
    	memset(du,0,sizeof(du));
    	cnt=0;
    	memset(head,0,sizeof(head));
    }
    
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    	{
    		cin>>dic[i];
    		len=dic[i].length();
    		tmp=dic[i];
    		insert();
    	}
    	for(int i=1;i<=n;i++)
    	{
    		tmp=dic[i];len=dic[i].length();
    		if(work()&&topsort()) op[++ans]=i;
    		clear();
    	}
    	printf("%d
    ",ans);
    	for(int i=1;i<=ans;i++)
    		cout<<dic[op[i]]<<endl;
    	return 0;
    }
    

    注意几点:连边的(tot)和字典树的指针(cnt)开始用混了。然后不管判断是否成功,每次都要清空(可能跑拓扑判定了)

  • 相关阅读:
    首发Zend Studio 9.0.2正式版注册破解
    PHP 中Cookie和Session的使用
    PHP设计模式职责和单例模式
    软件工程工具学习(1)Visio
    java复习(4)数字处理类
    java复习(1)java与C++区别
    微信开发(1)微信防撤回功能实现
    java复习(3)字符串、数组
    java复习(2)java基础杂记
    java复习(5)接口、继承、多态
  • 原文地址:https://www.cnblogs.com/nopartyfoucaodong/p/9917491.html
Copyright © 2011-2022 走看看