Brevity is Soul of Wit 二分圖匹配 將n個字符串縮短(slen

As we communicate, we learn much new information. However, the process of communication takes too much time. It becomes clear if we look at the words we use in our everyday speech.

We can list many simple words consisting of many letters: "information", "technologies", "university", "construction", "conservatoire", "refrigerator", "stopwatch", "windowsill", "electricity", "government" and so on. Of course, we can continue listing those words ad infinitum.

Fortunately, the solution for that problem has been found. To make our speech clear and brief, we should replace the initial words with those that resemble them but are much shorter. This idea hasn't been brought into life yet, that's why you are chosen to improve the situation.

Let's consider the following formal model of transforming words: we shall assume that one can use n words in a chat. For each words we shall introduce a notion of its shorter variant. We shall define shorter variant of an arbitrary word s as such word t, that meets the following conditions:

  • it occurs in s as a subsequence,
  • its length ranges from one to four characters.

In other words, the word t consists at least of one and at most of four characters that occur in the same order in the word s. Note that those characters do not necessarily follow in s immediately one after another. You are allowed not to shorten the initial word if its length does not exceed four characters.

You are given a list of n different words. Your task is to find a set of their shortened variants. The shortened variants of all words from the list should be different.

Input

The first line of the input file contains the only integer n (1 ≤ n ≤ 200). Then n lines contain a set of different non-empty words that consist of lowercase Latin letters. The length of each word does not exceed 10 characters.

Output

If the solution exists, print in the output file exactly n lines, where the i-th line represents the shortened variant of the i-th word from the initial set. If there are several variants to solve the problem, print any of them. If there is no solution, print -1.

Sample test(s)
input
6
privet
spasibo
codeforces
java
marmelad
normalno
output
pret
sps
cdfs
java
mama
norm
input
5
aaa
aa
a
aaaa
aaaaa
output
-1

//將字符串分解成多個子串,hash+二分圖匹配


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=400000;
struct Trie
{
    int idx;
    Trie* next[26];
};
Trie* root;
Trie temp[maxn];
int tp,index;
void reset(Trie* p)
{
    p->idx=-1;
    for(int i=0;i<26;i++) p->next[i]=NULL;
}
void init()
{
    tp=0;
    root=&temp[tp++];
    reset(root);
}
char str[maxn][5];
int insert(char *word)
{
    Trie* p=root;
    for(int i=0;word[i];i++)
    {
        int x=word[i]-'a';
        if(p->next[x]==NULL)
        {
            p->next[x]=&temp[tp++];
            reset(p->next[x]);
        }
        p=p->next[x];
    }
    if(p->idx==-1)
    {
        strcpy(str[++index],word);
        p->idx=index;
    }
    return p->idx;
}




const int N=400000;
/*初始化


注意 加邊時候X和Y統一標號,不是分別標號


加邊時按照總點數來加
cnt=0;
memset(head,-1,sizeof(head));
*/
int n;//X點數
int link[N];
int sa[N];
bool used[N];
int head[N],cnt;
struct TT
{
    int v,next;
}edge[N];
void addedge(int u,int v)
{
    edge[cnt].v=v;
    edge[cnt].next=head[u];
    head[u]=cnt++;
}
bool can(int t)
{
    for(int p=head[t];p!=-1;p=edge[p].next)
    {
        int v=edge[p].v;
        if(used[v]==false)
        {
            used[v]=1;
            if(link[v]==-1||can(link[v]))
            {
                link[v]=t;sa[t]=v;
                return true;
            }
        }
    }
    return false;
}
int MaxMatch()
{
    int num=0;
    memset(link,-1,sizeof(link));
    for(int i=1;i<=n;i++)
    {
        memset(used,false,sizeof(used));
        if(can(i)) num++;
    }
    return num;
}




char ch[5];
void dfs(char *s,int u,int len,int limt,int id,int now)
{
    if(now==limt)
    {
        ch[limt]='\0';
        int t=insert(ch);
        addedge(u,t);
        return ;
    }
    if(id==len) return ;
    ch[now]=s[id];
    dfs(s,u,len,limt,id+1,now+1);
    dfs(s,u,len,limt,id+1,now);
}
int main()
{
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    while(scanf("%d",&n)==1)
    {
        init();
        cnt=0;
        memset(head,-1,sizeof(head));
        index=n;
        for(int i=1;i<=n;i++)
        {
            char s[13];scanf("%s",s);
            int len=strlen(s);
            if(len<=4)
            {
                int t=insert(s);
                addedge(i,t);
            }
            else
            {
                dfs(s,i,len,1,0,0);
                dfs(s,i,len,2,0,0);
                dfs(s,i,len,3,0,0);
                dfs(s,i,len,4,0,0);
            }
        }
        int ans=MaxMatch();
        if(ans==n)
        {
            for(int i=1;i<=n;i++)
            {
                printf("%s\n",str[sa[i]]);
            }
        }
        else
        {
            printf("-1\n");
        }
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章