Matrix Gym

来源:互联网 发布:罗马斗兽场 知乎 编辑:程序博客网 时间:2024/06/03 05:54


用对角线匹配可选值

#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 0x3f3f3f3fint 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;}