[贪心+Trie] Codeforces #566A. Matching Names

来源:互联网 发布:淘宝设计教程 编辑:程序博客网 时间:2024/05/17 07:32

首先考虑直觉的贪心,每次找 LCP 尽量长的配对。是否正确呢?
考虑 abLCP 较长,cd 较短,如果我们互换组合,一定不会使答案增大,所以大概可以感受到贪心是对的。
接下来就是实现的问题了。容易想到 Trie。我们可以从叶往根合并,中途进行匹配。

#include<cstdio>#include<iostream>#include<algorithm>#include<string>#include<vector>#include<cstring>using namespace std;const int maxn=100005;int n,ans,tot;string a[maxn],b[maxn];pair<int,int> res[maxn];struct node{    node* ch[26];    vector<int> V1,V2;    node(){ memset(ch,0,sizeof(ch));V1.clear();V2.clear(); }} base[500000], *p_top=base, *root;typedef node* P_node;P_node newnode(){ return p_top++; }void Insert1(int id,string st){    P_node now=root;    for(int i=0;i<st.size();i++){        if(!now->ch[st[i]-'a']) now->ch[st[i]-'a']=newnode();        now=now->ch[st[i]-'a'];     }    now->V1.push_back(id);}void Insert2(int id,string st){    P_node now=root;    for(int i=0;i<st.size();i++){        if(!now->ch[st[i]-'a']) now->ch[st[i]-'a']=newnode();        now=now->ch[st[i]-'a'];     }    now->V2.push_back(id);}typedef node* P_node;void dfs(P_node p,int dep){    for(int i=0;i<=25;i++) if(p->ch[i]){        dfs(p->ch[i],dep+1);         for(auto j : p->ch[i]->V1) p->V1.push_back(j);        for(auto j : p->ch[i]->V2) p->V2.push_back(j);    }    while(p->V1.size()&&p->V2.size()){        ans+=dep;        res[++tot]=make_pair(p->V1[p->V1.size()-1],p->V2[p->V2.size()-1]);        p->V1.pop_back(); p->V2.pop_back();    }}int main(){    freopen("51nod1526.in","r",stdin);    freopen("51nod1526.out","w",stdout);    scanf("%d",&n);    root=newnode();    for(int i=1;i<=n;i++) cin >> a[i], Insert1(i,a[i]);    for(int i=1;i<=n;i++) cin >> b[i], Insert2(i,b[i]);    dfs(root,0);    printf("%d\n",ans);    for(int i=1;i<=n;i++) printf("%d %d\n",res[i].first,res[i].second);    return 0;}
原创粉丝点击