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.
  • 相关阅读:
    操纵持久化对象
    面阵和线扫工业相机选型
    线扫描镜头简介及选型
    Halcon的anisotropic_diffusion()函数,用于对图像进行各向异性散射增强处理
    VB、C#等高级语言与三菱PLC(Q系列、L系列、FX系列、A系列)串口、以太网通讯的DLL及源代码
    Halcon学习笔记之支持向量机
    C#中使用byte[]数据,生成Bitmap(256色 灰度 BMP位图)源代码
    Halcon学习SVM
    利用MLP(多层感知器)创建一个新的OCR分级器
    Halcon中OCR的实现及关键函数解析
  • 原文地址:https://www.cnblogs.com/wang9897/p/10333777.html
Copyright © 2011-2022 走看看