hdu 2819 Swap(二分图匹配)

来源:互联网 发布:淘宝xboxone手柄假货 编辑:程序博客网 时间:2024/05/16 15:21

左边的点集是列标号,右边的点集是在初始时为每一行分配的id

构图:对每个左边的定点,枚举右边的定点,如果右边的行在相应列上为1,则连上一条边

然后找一个完备匹配

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <string>#include <vector>using namespace std;#define REP(i,s,t) for(int (i)=(s);(i)<=(t);++(i))typedef long long LL;const int maxn = 105;vector<int> g[maxn + 5];int cx[maxn + 5], cy[maxn+5];int vis[maxn + 5];int m[maxn + 5][maxn + 5];int a[maxn+5];int pos[maxn+5];int save[maxn+5][2];bool match(int x) {    int len = g[x].size();    int node;    for (int i=0;i<len;++i)        if (!vis[g[x][i]]) {            node = g[x][i];            vis[node] = 1;            if (cy[node] == -1 || match(cy[node])) {                cy[node] = x;                cx[x] = node;                return true;            }        }    return false;}int main() {    int n;    while (cin >> n) {        REP(i, 0, n-1)            REP(j, 0, n-1)                scanf("%d",&m[i][j]);        REP(i, 0, n-1)            g[i].clear();        REP(i, 0, n-1)            REP(j, 0, n-1)                if (m[j][i])                    g[i].push_back(j);        memset(cx, -1, sizeof(cx));        memset(cy, -1, sizeof(cy));        REP(i, 0, n-1) {            if (cx[i] == -1) {                memset(vis, 0, sizeof(vis));                match(i);            }        }        bool ok = true;        REP(i, 0, n-1)            if (cx[i] == -1) {                ok = false;                break;            }        if (!ok) {            cout << -1 << endl;        } else {            REP(i, 0, n-1) {a[i] = i;pos[i] = i;}            int ans_cnt = 0;            REP(i, 0, n-1) {                if (cx[i] != a[i]) {                    save[ans_cnt][0] = i+1;save[ans_cnt++][1] = pos[cx[i]]+1;                    int tmp = a[i];                    a[i] = cx[i];                    a[pos[cx[i]]] = tmp;                    pos[tmp] = pos[cx[i]];                    pos[cx[i]] = i;                }            }            cout << ans_cnt << endl;            REP(i, 0, ans_cnt-1)                printf("R %d %d\n", save[i][0], save[i][1]);        }    }    return 0;}


0 0