题目链接
思路:我们建字典树的时候存一下当前这个点对应的两个数组a和b的编号,然后把字典树像普通树一样去dfs,我们贪心的选深度深的,因为深度越深就说明两个字符串匹配的越多,每一层的时候可以暴力枚举匹配一样就行。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+1;
int n,cnt=0,tree[maxn][27],sum,visa[maxn],visb[maxn];
vector<pair<int,int>>ans;
vector<int>a[maxn],b[maxn];
char s[maxn];
void insert(vector<int>a[],int id)
{
int u=0,len=strlen(s);
a[u].push_back(id);
for(int i=0;i<len;++i)
{
if(!tree[u][s[i]-'a']) tree[u][s[i]-'a']=++cnt;
u=tree[u][s[i]-'a'];
a[u].push_back(id);
}
}
void dfs(int x,int deep)
{
for(int i=0;i<26;++i)
if(tree[x][i]) dfs(tree[x][i],deep+1);
for(int i=0;i<a[x].size();++i)
{
if(visa[a[x][i]]) continue;
for(int j=0;j<b[x].size();++j)
{
if(visb[b[x][j]]) continue;
visb[b[x][j]]=visa[a[x][i]]=1;
sum+=deep;
ans.push_back({a[x][i],b[x][j]});
break;
}
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%s",s),insert(a,i);
for(int i=1;i<=n;++i) scanf("%s",s),insert(b,i);
dfs(0,0);
printf("%d\n",sum);
for(auto i:ans) printf("%d %d\n",i.first,i.second);
}