给定一个数组arr1包含整数1..N和另一个数组arr2包含整数1..M 。 arr1的每个元素都映射到arr2中的多个元素。任务是最大化两个阵列之间可能的一对一映射的数量。
这里一对一的映射意味着arr1的唯一元素必须映射到arr2的唯一元素。
映射以对V的向量的形式给出,其中V.first()表示arr1的元素,而V.second()表示arr2的元素。
例子:
Input: N = 3, M = 3
arr1[] = {1, 2, 3}
arr2[] = {1, 2, 3}
V = { {1, 1}, {2, 1}, {2, 2},
{3, 1}, {3, 2}, {3, 3} }
Output: 3
Explanation:
If we carefully see here mappings are
1 --------> {1}
2 --------> {1, 2}
3 --------> {1, 2, 3}
so, maximum number of unique pairings
can be done as
1 --------> {1}
2 --------> {2}
3 --------> {3}
Input: N = 3, M = 1
V = { {1, 1}, {2, 1}, {3, 1} };
Output: 1
Explanation:
Either 1 can be mapped or 2 or 3.
so maximum one mapping is possible.
方法:这里使用的方法是贪婪。
预处理步骤
我们得到了一个向量对,其中包含未分类的映射信息,例如-
因此,我们将此映射信息转换为集合映射的向量。
例如:
这以一对多映射形式表示信息。
下图可以很容易地理解这一点
步骤:
- 在arr1 []中找到与arr2 []元素的映射数最少的元素。
- 将此元素映射到其对应集合的第一个元素。
- 删除此元素的所有映射。
- 同时从arr2 []中删除所有包含元素的映射,这些映射已经被映射。
- 对arr1 []的所有元素重复上述四个步骤。
下面是上述方法的实现:
// C++ Program to convert many to many mapping
// to maximum no of one to one mappings
#include
using namespace std;
// Returns the maximum number
// of one to one mappings between two arrays
int FindMax(vector >& V, int N, int M)
{
int ans = 0;
// Stores whether an element
// from the first array is used in mapping
bool* is_paired = new bool[N];
// Contains mapping in sorted form
vector > mapping(N + 1);
// Initialize all the elements
// of first array unused
memset(is_paired, sizeof(is_paired), false);
// Insert mappings in sorted form
for (int i = 0; i < V.size(); i++) {
mapping[V[i].first].insert(V[i].second);
}
// While there is always at least one element
// which can be mapped to a unique element
while (true) {
int lowest = -1;
// Finds element to be mapped
for (int i = 1; i <= N; i++) {
// There is mapping possible
if (mapping[i].size() > 0) {
if (lowest == -1)
lowest = i;
else if (mapping[i].size()
< mapping[lowest].size())
lowest = i;
}
}
if (lowest == -1)
break;
// Element used in the mapping
is_paired[lowest] = true;
int remove = *mapping[lowest].begin();
// Delete all the mappings of used element
for (int i = 1; i <= N; i++) {
mapping[i].erase(remove);
if (i == lowest) {
mapping[i].clear();
}
}
ans++;
}
return ans;
}
// Main Function
int main()
{
int N = 3;
int M = 3;
int arr1[] = { 1, 2, 3 };
int arr2[] = { 1, 2, 3 };
vector >
V{ { 1, 1 }, { 2, 1 }, { 2, 2 }, { 3, 1 }, { 3, 2 }, { 3, 3 } };
cout << FindMax(V, N, M) << endl;
return 0;
}
输出:
3
时间复杂度: 其中x为最大,没有一对一的映射。