目前最大的二分匹配算法是O(√VE)。
这是我要解决上述问题的算法: 给定两组S1和S2以及它们之间的E边。
步骤1:根据程度对S1和S2进行升序排序
第2步:按排序顺序选择集合中的元素,并将其分配给另一个集合中的下一个空闲元素,然后计算匹配次数。
第3步:在S1上执行第2步,然后在S2上执行。
第4步:最多进行第3步。
这使得算法的复杂度高于O(Vlog(V)+(V + E))。
我无法证明上述算法的正确性,因此任何人都可以帮助解决上面示例失败的任何反例,因为该算法无法解决spoj问题MATCHING,因此算法是错误的,但可以' t找出反例。
谢谢
#include<bits/stdc++.h>
#define ll long long int
using namespace std;
int main(){
ll c,b,p;
cin >> c >> b >> p;
c+=1;
b+=1;
ll mx = max(c,b);
c =mx;
b =mx;
vector<ll> adjcow[c];
vector<ll> adjbull[b];
for(ll i=0; i<p; i++){
ll x,y;
cin >> x >> y;
adjcow[x].push_back(y);
adjbull[y].push_back(x);
}
/*
for(ll i=0; i<c; i++){
cout << i << " ";
for(auto x:adjcow[i])
cout << x << " ";
cout << "\n";
}
for(ll i=0; i<b; i++){
cout << i << " ";
for(auto x : adjbull[i])
cout << x << " ";
cout << endl;
}
*/
vector<pair<ll, ll>> deg1(c);
vector<pair<ll, ll>> deg2(b);
for(ll i=0; i<c; i++){
ll count = 0;
for(auto x: adjcow[i])
count++;
deg1[i] = {count, i};
}
for(ll i=0; i<b; i++){
ll count = 0;
for(auto x: adjbull[i])
count++;
deg2[i] = {count,i};
}
sort(deg1.begin(), deg1.end());
sort(deg2.begin(), deg2.end());
vector<bool> isTaken1(c,0);
vector<bool> isTaken2(b,0);
/*
for(ll i=0; i<c; i++)
cout << deg1[i].first << " " << deg1[i].second << ", ";
cout << endl;
for(ll i=0; i<b; i++)
cout << deg2[i].first <<" "<< deg2[i].second << ", ";
cout << endl;
*/
ll ansCow =0;
for(auto x:deg1){
ll node = x.second;
for(auto u: adjcow[node]){
if(isTaken1[u]==0){
// cout << node << "-> " << u << "\n";
isTaken1[u] = 1;
ansCow++;
break;
}
}
}
//cout << "\n\n";
ll ansBull =0;
for(auto x:deg2){
ll node = x.second;
for(auto u: adjbull[node]){
if(isTaken2[u]==0){
// cout << node << "->" << u << "\n";
isTaken2[u] = 1;
ansBull++;
break;
}
}
}
cout << max(ansCow, ansBull) << "\n";
}
输入::
5 4 6
5 2
1 2
4 3
3 1
2 2
4 4