CodeForces 566 A Matching Names(Trie 匹配LCP和最大)
来源:互联网 发布:mac可以玩lucky dog1 编辑:程序博客网 时间:2024/06/07 06:09
题意:有n个A字符串和n个B字符串,问如何匹配能使LCP(最长公共前缀)和最大。
思路:将A和B分别插入Trie,节点保存的是具有该前缀的字符串id,然后对Trie进行dfs,优先选择深的匹配,并标记。 然后回溯去
匹配,被标记过的不再进行匹配。
代码:
#include<bits/stdc++.h>using namespace std;const int maxnode = 8e5+5;int ch[maxnode][26], sz;char str[maxnode];bool vis[maxnode][2];int match[maxnode];vector<int> val[maxnode][2];void init(){ sz = 1; memset(ch[0], 0, sizeof(ch[0]));}void Insert(char *s, int id, int v){ int u = 0; int len = strlen(s); val[u][id].push_back(v); //最后几个可能一个字符都不匹配,所以一定要在根处也加上 for(int i = 0; i < len; i++) { if(ch[u][s[i]-'a'] == 0) { memset(ch[sz], 0, sizeof(ch[sz])); val[sz][id].clear(); ch[u][s[i]-'a'] = sz++; } u = ch[u][s[i]-'a']; val[u][id].push_back(v); }}int dfs(int dep, int u){ int ans = 0; for(int i = 0; i < 26; i++) if(ch[u][i]) //尽可能深 ans += dfs(dep+1, ch[u][i]); vector<int> tmp[2]; for(int i = 0; i < 2; i++) for(int j = 0; j < val[u][i].size(); j++) if(!vis[val[u][i][j]][i]) //到这一层还没匹配过的具有公共前缀的都可以进行匹配了 已经是最优了 tmp[i].push_back(val[u][i][j]); int num = min(tmp[0].size(), tmp[1].size()); //能匹配的对数 ans += dep*num; for(int i = 0; i < num; i++) { match[tmp[0][i]] = tmp[1][i]; vis[tmp[0][i]][0] = vis[tmp[1][i]][1] = 1; //匹配并标记用过 } return ans;}int main(void){ int n; while(cin >> n) { init(); memset(vis, 0, sizeof(vis)); for(int i = 1; i <= n; i++) scanf(" %s", str), Insert(str, 0, i); for(int i = 1; i <= n; i++) scanf(" %s", str), Insert(str, 1, i); printf("%d\n", dfs(0, 0)); for(int i = 1; i <= n; i++) printf("%d %d\n", i, match[i]); } return 0;}
阅读全文
1 0
- CodeForces 566 A Matching Names(Trie 匹配LCP和最大)
- 多对多LCP和最大 Trie DFS CodeForces - 566A Matching Names
- [贪心+Trie] Codeforces #566A. Matching Names
- codeforces 566A Matching Names
- CodeForces - 566A Matching Names(字典树)
- lcp计数 (Trie)
- Matching Names(Trie树)-(VK Cup 2015 - Finals, online mirror)
- Trie(字典树):大LCP
- 【字符串】【Trie】lcp 题解
- leetcode Wildcard Matching ,Regular Expression Matching (正则表达式匹配和通配符匹配)
- codeforces367(字符串hash求lcp比较大小,Trie解最大异或问题)
- Codeforces Round #367 (Div. 2)-Vasiliy's Multiset-最大异或和-trie
- CodeForces 501A Contest(最大得分)
- 一个简单最大正向匹配(Maximum Matching)MM中文分词算法的实现
- Codeforces Round #290 (Div. 1)A. Fox And Names
- Codeforces Round #290 (Div. 1) A. Fox And Names
- BZOJ3261: 最大异或和(可持续化Trie)
- bzoj3261 最大异或和(可持久化Trie)
- JSP EL表达式 学习 应用
- 思维导图---区块链技术和区块链应用
- Combination Sum
- 深入spring cloud(1)
- POJ1598-C语言
- CodeForces 566 A Matching Names(Trie 匹配LCP和最大)
- git学习笔记2——ProGit2
- 【Leetcode】【python】Factorial Trailing Zeroes
- springmvc文件上传
- C#简单工厂设计模式实现计算器
- Linux中的软连接与硬链接
- Matlab的Gauss_Seidel迭代方法解线性方程组
- IOS helloworld
- Python学习笔记(九)——异常处理