您的位置:首页 > 其它

Matrix Gym - 100741F 匈牙利算法(最大二分图匹配)

2017-08-22 22:04 411 查看
用对角线匹配可选值

#include <iostream>
#include <string>
#include <cstring>
#include <vector>
#include <set>
#include <stack>
#include <algorithm>
#include <iterator>
#include <queue>
#include <cmath>
#include <map>
#include <cstdio>

using namespace std;
#define maxn (300 + 7)
#define INF 0x3f3f3f3f
int n;
int mp[maxn][maxn];
vector<int> a[3*maxn];
map<int, int> f;
set<int> st;
int ans[maxn*3];

int solve(int id) {
//cout << " 56565 " << endl;
for(int i = 0; i < a[id].size(); ++i) {
int t = a[id][i];
if(st.count(t) == 0) {
st.insert(t);

if(f[t] == 0 || solve(f[t])) {

f[t] = id;
ans[id] = t;
return 1;
}
}
}
return 0;
}

int main() {
scanf("%d", &n);
for(int i = 0; i < n; ++i) {
for(int j = 0; j < n; ++j)
scanf("%d", &mp[i][j]);
}
int id = 1;
for(int i = n-1; i >= 0;--i) {
int t = i;
for(int j = 0; t < n;) {
a[id].push_back(mp[t][j]);
t++; j++;
}
id++;
}

for(int j = 1; j < n; ++j) {
int t = j;
for(int i = 0; t < n ; ) {
a[id].push_back(mp[i][t]);
i++; t++;
}
id++;
}
int m = id-1;

int cnt = 0;
f.clear();
for(int i = 1; i <= m; ++i) {
st.clear();
if(solve(i)) cnt++;
}
//cout << " +++ " << endl;
if(cnt == 2*n - 1) {//cout << " 2333 duile" << endl;
cout << "YES";
for(int i = 1; i <= m; ++i) {
cout << " " << ans[i];
}
}
else puts("NO");

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: