VK Cup 2015 - Finals, online mirror A. Matching Names(字典树+dfs+贪心)

题目链接
在这里插入图片描述
在这里插入图片描述
思路:我们建字典树的时候存一下当前这个点对应的两个数组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);
}
发布了283 篇原创文章 · 获赞 0 · 访问量 7311

猜你喜欢

转载自blog.csdn.net/qq_42479630/article/details/105058078