hdu2819 Swap (+ bipartite graph matching using the matching results)

Problem Description

Given a N * N matrix, each element is equal to 0 or 1. You can swap any two lines or any of the two. Can you find a way to make all of the diagonal elements are equal to 1?

Entry

Input There are several test cases. The first line of each test case is an integer N (1 <= N <= 100). Then the N rows, each row comprising N digits (0 or 1), spatially separated, represents N * N matrix.

Export

For each test case, the first row contains the number of M, and M rows, the format is "R ab" or "C ab", indicates that the exchange line and a B line, and a row or column exchange of b. (1 <= a, b < = N). Any correct answer will be accepted, but it should be more than 1,000.
If it is impossible to make all of the diagonal elements are equal to 1, then the output only contains a "-1" elements.

analysis:

First seek the maximum matching, if not equal to n explain the maximum matching impossible to satisfy conditions (similar to 'put chess car' that title).
I thought the match would be used in determining the next line by line, I really exchange traded. .
That is, starting from the first, if not equal to 1 on the diagonal, search down, search the complete exchange on a whole line can become a swap.
But this infinite wa, (later thought know why)

Correct answer is using the matching result, not only to ensure the number of exchanges and certainly correct.
Others see the code learned (hard to explain, look at the code directly think).

This problem deepened my understanding of the matching record on the spot!

code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
typedef long long ll;
const int inf=0x3f3f3f3f;
const int inn=0x80808080;
using namespace std;
const int maxm=105;
int g[maxm][maxm];
int mark[maxm];
int now[maxm];
int n;
int dfs(int x){
    for(int i=1;i<=n;i++){
        if(g[x][i]&&!mark[i]){
            mark[i]=1;
            if(!now[i]||dfs(now[i])){
                now[i]=x;
                return 1;
            }
        }
    }
    return 0;
}
int main(){
    while(cin>>n){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                cin>>g[i][j];
            }
        }
        int ans=0;
        memset(now,0,sizeof now);
        for(int i=1;i<=n;i++){
            memset(mark,0,sizeof mark);
            ans+=dfs(i);
        }
        if(ans!=n){
            cout<<-1<<endl;
            continue;
        }
        vector<int>aa;
        vector<int>bb;
        for(int i=1;i<=n;i++){
            if(now[i]!=i){
                for(int j=i+1;j<=n;j++){
                    if(now[j]==i){
                        aa.push_back(i);//注意这里交换的是列,所以是C a b
                        bb.push_back(j);//
                        swap(now[i],now[j]);
                        break;
                    }
                }
            }
        }
        printf("%d\n",aa.size());
        for(int i=0;i<(int)aa.size();i++){
            printf("C %d %d\n",aa[i],bb[i]);
        }
    }
    return 0;
}


Guess you like

Origin blog.csdn.net/weixin_44178736/article/details/92800545