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.
  • 相关阅读:
    div地图中display设置为none引起的报错
    onclick事件传参
    获取,设置任意标签的任意属性值
    ajax局域变量赋值给全局变量
    eclipse整合maven打包的时候跳过测试
    测网络ip,端口互通命令
    关于局域网地址ping不通的问题
    Error starting static Resources java.lang.IllegalArgumentException: Document base F:Soft omcatwebappspms-site does not exist or is not a readable directory
    回顾创建项目报错
    记录一次webpackJsonp is not defined
  • 原文地址:https://www.cnblogs.com/wang9897/p/10333777.html
Copyright © 2011-2022 走看看