zoukankan      html  css  js  c++  java
  • [BZOJ]3012: [Usaco2012 Dec]First! trie树+拓扑排序

    题解: 首先可以知道 某一个串存在前缀串则这个串必然不能字典序最小  所以我们直接对长度排序然后逐次加入trie树中  然后我们考虑当前串能成为最小 必须一层层满足对应的限制条件 然后拓扑check一下就行了

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <stack>
    #include <string>
    #include <queue>
    #include <cmath>
    #include <set>
    #include <map>
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define link(x) for(edge *j=h[x];j;j=j->next)
    #define inc(i,l,r) for(int i=l;i<=r;i++)
    #define dec(i,r,l) for(int i=r;i>=l;i--)
    const int MAXN=3e5+10;
    const double eps=1e-8;
    #define ll long long
    using namespace std;
    struct edge{int t;edge*next;}e[905],*h[26],*o=e;
    void add(int x,int y){o->t=y;o->next=h[x];h[x]=o++;}
    ll read(){
        ll x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    
    typedef struct node{
        int id;string s;
    }node;
    node str[MAXN];
    
    bool cmp(node aa,node bb){return aa.s.length()<bb.s.length();}
    
    typedef struct Node{
        int ch[26],sz,id;
    }Node;
    Node d[MAXN];
    int rt,cnt;
    void newnode(int &x){
        x=++cnt;
        d[x].sz=d[x].id=0;
        for(int i=0;i<26;i++)d[x].ch[i]=0;
    }
    
    void insert(string s,int id){
        int len=s.length();int temp=rt;
        bool flag=0;
        for(int i=0;i<len;i++){
    	int t=s[i]-'a';
    	if(!d[temp].ch[t]){break;}
    	temp=d[temp].ch[t];
    	if(d[temp].id){flag=1;break;}
        }
        if(flag)return ;
        temp=rt;
        for(int i=0;i<len;i++){
    	int t=s[i]-'a';
    	if(!d[temp].ch[t])newnode(d[temp].ch[t]);
    	temp=d[temp].ch[t];d[temp].sz++;
        }
        d[temp].id=id;
    }
    
    int Edge[31][31];
    bool vis[MAXN];
    int du[MAXN],ans1;
    queue<int>que;
    bool check(){
        inc(i,0,25)if(!du[i])que.push(i);
        while(!que.empty()){
    	int x=que.front();que.pop();
    	link(x){
    	    du[j->t]--;
    	    if(!du[j->t])que.push(j->t);
    	}
        }
        inc(i,0,25)if(du[i])return 0;
        return 1;
    }
    
    void dfs(int x){
        if(d[x].id){
    	memset(h,0,sizeof(h));o=e;
    	inc(i,0,25)du[i]=0;
    	inc(i,0,25)inc(j,0,25)if(Edge[i][j])add(i,j),du[j]++;
    	if(check())vis[d[x].id]=1,ans1++;
    	return ;
        }
        for(int i=0;i<26;i++){
    	if(!d[x].ch[i])continue;
    	for(int j=0;j<26;j++){
    	    if(j!=i&&d[x].ch[j])Edge[i][j]++;
    	}
    	dfs(d[x].ch[i]);
    	for(int j=0;j<26;j++){
    	    if(j!=i&&d[x].ch[j])Edge[i][j]--;
    	}	
        }
    }
    
    string S[MAXN];
    
    int main(){
        ios::sync_with_stdio(false);
        ans1=0;
        int n;cin>>n;
        inc(i,1,n)cin>>str[i].s,str[i].id=i,S[i]=str[i].s;
        sort(str+1,str+n+1,cmp);
        inc(i,1,n)insert(str[i].s,str[i].id);
        dfs(rt);
        cout<<ans1<<"
    ";
        inc(i,1,n)if(vis[i])cout<<S[i]<<"
    ";
    }
    

      

    3012: [Usaco2012 Dec]First!

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 328  Solved: 159
    [Submit][Status][Discuss]

    Description

    Bessie has been playing with strings again. She found that by changing the order of the alphabet she could make some strings come before all the others lexicographically (dictionary ordering). For instance Bessie found that for the strings "omm", "moo", "mom", and "ommnom" she could make "mom" appear first using the standard alphabet and that she could make "omm" appear first using the alphabet "abcdefghijklonmpqrstuvwxyz". However, Bessie couldn't figure out any way to make "moo" or "ommnom" appear first. Help Bessie by computing which strings in the input could be lexicographically first by rearranging the order of the alphabet. To compute if string X is lexicographically before string Y find the index of the first character in which they differ, j. If no such index exists then X is lexicographically before Y if X is shorter than Y. Otherwise X is lexicographically before Y if X[j] occurs earlier in the alphabet than Y[j].

    给定n个总长不超过m的互不相同的字符串,现在你可以任意指定字符之间的大小关系。问有多少个串可能成为字典
    序最小的串,并输出这些串。n <= 30,000 , m <= 300,000

    Input

    * Line 1: A single line containing N (1 <= N <= 30,000), the number of strings Bessie is playing with.

    * Lines 2..1+N: Each line contains a non-empty string. The total number of characters in all strings will be no more than 300,000. All characters in input will be lowercase characters 'a' through 'z'. Input will contain no duplicate strings.

    Output

     * Line 1: A single line containing K, the number of strings that could be lexicographically first.

     * Lines 2..1+K: The (1+i)th line should contain the ith string that could be lexicographically first. Strings should be output in the same order they were given in the input. 

    Sample Input

    4
    omm
    moo
    mom
    ommnom
    INPUT DETAILS: The example from the problem statement.

    Sample Output

    2
    omm
    mom

    OUTPUT DETAILS: Only "omm" and "mom" can be ordered first.
  • 相关阅读:
    Request.ServerVariables
    asp.net 枚举
    MSSQL批量替换语句 在SQL SERVER中批量修改替换数据
    由于 ASP.NET 进程标识对全局程序集缓存没有读权限,因此未能执行请求
    mongodb 下载地址,mongodb.dll 下载
    mongodb 常用操作(转)
    mssql 列出数据库中的所有表
    jpg图片在火狐中和ie中格式区别
    Ndo 新版本发布
    消息总线设计系列之 调停者模式
  • 原文地址:https://www.cnblogs.com/wang9897/p/10333777.html
Copyright © 2011-2022 走看看