• 偏序+拓扑序+字典树


    题目描述 

    给定n个字符串,互不相等,你可以任意指定字符之间的大小关系(即重定义字典序),求有多少个串可能成为字典序最小的串,并输出它们

    输入描述:

    第一行一个数表示n
    之后n行每行一个字符串表示给定的字符串

    输出描述:

    第一行输出一个数x表示可行的字符串个数
    之后输出x行,每行输出一个可行的字符串
    输出的顺序和输入的顺序一致
    示例1

    输入

    6
    mcfx
    ak
    ioi
    wen
    l
    a

    输出

    5
    mcfx
    ioi
    wen
    l
    a
    #include <bits/stdc++.h>
    #define INF 0x3f3f3f3f
    using namespace std;
    typedef struct node{
        string s;int biao;
        friend bool operator <(node aa,node bb){
            return aa.s.length()<bb.s.length();
        }
    }node;
    string str[30005];
    node dd[30005];
    int cnt,root;
    typedef struct nop{
        int a[26],ans;
    }nop;
    nop d[300005];
    bool vvis[30005];
    int newnode(){
        cnt++;d[cnt].ans=0;
        for(int i=0;i<26;i++) d[cnt].a[i]=0;
        return cnt;
    }
    void inset(string s,int tt){
        int len=s.length();int temp=root;
        for(int i=0;i<len;i++){
            int t=s[i]-'a';
            if(d[temp].a[t]==0){
                d[temp].a[t]=newnode();
            }
            temp=d[temp].a[t];
            if(d[temp].ans!=0){
            	vvis[tt]=1;return ;
    		}
            if(i==len-1){
    		d[temp].ans=tt;
    		}
        }
         return ;
    }
    vector<int>v_[26];
    int dis[26];queue<int>que;
    bool check(){
    	memset(dis,0,sizeof(dis));
    	for(int i=0;i<26;i++){
    		for(int j=0;j<v_[i].size();j++){
    			dis[v_[i][j]]++;
    		}
    	}
    	while(!que.empty()) que.pop();
    	for(int i=0;i<26;i++){
    		if(!dis[i]) que.push(i);
    	}
    	if(que.empty()) return 0;
    	while(!que.empty()){
    		int t=que.front();que.pop();
    		for(int i=0;i<v_[t].size();i++){
    			dis[v_[t][i]]--;
    			if(dis[v_[t][i]]==0) que.push(v_[t][i]);
    		}
    	}
    	for(int i=0;i<26;i++){
    		if(dis[i]!=0) return 0;
    	}
    	return 1;
    }
    int main(){
        int n;cin>>n;
        for(int i=1;i<=n;i++){
            cin>>str[i];
            dd[i].s=str[i];dd[i].biao=i;
        }
        sort(dd+1,dd+n+1);
        root=newnode();
     	for(int i=1;i<=n;i++){
     		inset(dd[i].s,dd[i].biao);
    	 }
    	 for(int i=1;i<=n;i++){
    	 	if(vvis[i]) continue;
    	 	int len=str[i].length();
    	 	int temp=root;
    	 	for(int j=0;j<len;j++){
    	 		int t=str[i][j]-'a';
    	 		for(int k=0;k<26;k++){
    	 			if(d[temp].a[k]!=0&&k!=t){
    	 				v_[t].push_back(k);
    				 }
    			 }
    			 temp=d[temp].a[t];
    		 }
    		 if(!check()) vvis[i]=1; 
    		 for(int j=0;j<26;j++) v_[j].clear();
    	 }
    	 int cnt=0;
    	 for(int i=1;i<=n;i++){
    	 	if(vvis[i]==1) continue;
    	 	cnt++;
    	 }
    	 cout<<cnt<<endl;
    	 for(int i=1;i<=n;i++){
    	 	if(vvis[i]==1) continue;
    	 	cout<<str[i]<<endl;
    	 }
        return 0;
    }
    

      

  • 相关阅读:
    HDU.2087 剪花布条
    一个acm过来人的心得
    一个acm过来人的心得
    HDU.2190 悼念512汶川大地震遇难同胞——重建希望小学
    HDOJ.2501 Tiling_easy version
    HDOJ.2501 Tiling_easy version
    HDU
    poj3216 Prime Path(BFS)
    poj1426 Find The Multiple (DFS)
    Rikka with Nickname (简单题)
  • 原文地址:https://www.cnblogs.com/wang9897/p/8368339.html
Copyright © 2020-2023  润新知