zoukankan      html  css  js  c++  java
  • HDU 2819

    题目链接:https://cn.vjudge.net/problem/HDU-2819

    Given an N*N matrix with each entry equal to 0 or 1. You can swap any two rows or any two columns. Can you find a way to make all the diagonal entries equal to 1?

    InputThere are several test cases in the input. The first line of each test case is an integer N (1 <= N <= 100). Then N lines follow, each contains N numbers (0 or 1), separating by space, indicating the N*N matrix.OutputFor each test case, the first line contain the number of swaps M. Then M lines follow, whose format is “R a b” or “C a b”, indicating swapping the row a and row b, or swapping the column a and column b. (1 <= a, b <= N). Any correct answer will be accepted, but M should be more than 1000. 

    If it is impossible to make all the diagonal entries equal to 1, output only one one containing “-1”. 
    Sample Input

    2
    0 1
    1 0
    2
    1 0
    1 0

    Sample Output

    1
    R 1 2
    -1

    题意:

    给出一个N*N的01矩阵,要求你通过一些行交换或者列交换使得矩阵的主对角线上全为1;

    题解:

    不难想象,进行行列缩点,如果某个位置aij等于1,就往二分图中加入一条边( i , j ),如果求出最大匹配等于N,说明可以通过行列的变换得到目标矩阵;

    然后根据匹配情况,输出相应的交换步骤即可;

    AC代码:

    #include<bits/stdc++.h>
    #define MAX 103
    #define INF 0x3f3f3f3f
    using namespace std;
    int n,matrix[MAX][MAX];
    
    struct Hopcroft_Karp{
        int edge[MAX][MAX],Mx[MAX],My[MAX],Nx,Ny;
        int dx[MAX],dy[MAX],dis;
        bool vis[MAX];
        void init(int uN,int vN)
        {
            Nx=uN, Ny=vN;
            for(int i=1;i<=uN;i++) for(int j=1;j<=vN;j++) edge[i][j]=0;
        }
        void addedge(int u,int v){edge[u][v]=1;}
        bool searchP()
        {
            queue<int> Q;
            dis=INF;
            memset(dx,-1,sizeof(dx));
            memset(dy,-1,sizeof(dy));
            for(int i=1;i<=Nx;i++)
            {
                if(Mx[i]==-1)
                {
                    Q.push(i);
                    dx[i]=0;
                }
            }
            while(!Q.empty())
            {
                int u=Q.front();Q.pop();
                if(dx[u]>dis) break;
                for(int v=1;v<=Ny;v++)
                {
                    if(edge[u][v] && dy[v]==-1)
                    {
                        dy[v]=dx[u]+1;
                        if(My[v]==-1) dis=dy[v];
                        else
                        {
                            dx[My[v]]=dy[v]+1;
                            Q.push(My[v]);
                        }
                    }
                }
            }
            return dis!=INF;
        }
        bool dfs(int u)
        {
            for(int v=1;v<=Ny;v++)
            {
                if(!vis[v] && edge[u][v] && dy[v]==dx[u]+1)
                {
                    vis[v]=1;
                    if(My[v]!=-1 && dy[v]==dis) continue;
                    if(My[v]==-1 || dfs(My[v]))
                    {
                        My[v]=u;
                        Mx[u]=v;
                        return true;
                    }
                }
            }
            return false;
        }
        int max_match()
        {
            int ret=0;
            memset(Mx,-1,sizeof(Mx));
            memset(My,-1,sizeof(My));
            while(searchP())
            {
                memset(vis,0,sizeof(vis));
                for(int i=1;i<=Nx;i++) if(Mx[i]==-1 && dfs(i)) ret++;
            }
            return ret;
        }
    }HK;
    
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            HK.init(n,n);
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    scanf("%d",&matrix[i][j]);
                    if(matrix[i][j]) HK.addedge(i,j);
                }
            }
    
            int max_match=HK.max_match();
            if(max_match==n)
            {
                queue< pair<int,int> > output;
                for(int j=1;j<=n;j++)
                {
                    int u1=j, u2=HK.My[j];
                    int v1=j, v2=HK.Mx[j];
                    if(u1!=u2)
                    {
                        output.push(make_pair(u1,u2));
                        HK.My[v1]=u1, HK.My[v2]=u2;
                        HK.Mx[u1]=v1, HK.Mx[u2]=v2;
                    }
                }
    
                printf("%d
    ",output.size());
                while(!output.empty())
                {
                    printf("R %d %d
    ",output.front().first,output.front().second);
                    swap(matrix[output.front().first],matrix[output.front().second]);
                    output.pop();
                }
            }
            else printf("-1
    ");
        }
    }

    PS.刚开始还以为HK算法的模板出错了,吓死了……

    PS.注意更改匹配情况时,match数组的变更;

  • 相关阅读:
    算法竞赛进阶指南--lowbit运算,找到二进制下所有是1的位
    linux
    conda配置安装pytorch
    anaconda的安装及使用
    python操作mysql
    python生成文字云
    决策树基本原理
    Ubuntu截图软件
    ubuntu安装teamviewer
    k-最近邻算法基本原理
  • 原文地址:https://www.cnblogs.com/dilthey/p/7702023.html
Copyright © 2011-2022 走看看