zoukankan      html  css  js  c++  java
  • HDU 2819 Swap(记录二分匹配的过程)

    Problem Description:
    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?
     
    Input:
    There 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.
     
    Output:
    For 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的矩阵,所有的元素都是0或1,现在问能不能只通过交换行或者是列就能让该矩阵的主对角线的元素都是1,如果不能输出-1,如果能,则输出要改变的步数,并将改变的行或列输出(即R a b),或者(C a b)。

    即需要判断该矩阵行与列的最大匹配数是否等于n,如果不等,则不能达到要求,如果等于则达到要求,记录下求最大匹配的过程

    详细解释:http://www.cnblogs.com/jzlikewei/archive/2012/07/09/2583608.html

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    
    const int N=110;
    
    struct node
    {
        int x, y;
    }no[N];
    int G[N][N], vis[N], match[N], n;
    
    int Find(int u)
    {
        int i;
    
        for (i = 1; i <= n; i++)
        {
            if (!vis[i] && G[u][i])
            {
                vis[i] = 1;
    
                if (!match[i] || Find(match[i]))
                {
                    match[i] = u;
    
                    return 1;
                }
            }
        }
    
        return 0;
    }
    
    int main ()
    {
        int i, j, ans, k;
    
        while (scanf("%d", &n) != EOF)
        {
            memset(G, 0, sizeof(G));
            memset(match, 0, sizeof(match));
            ans = k = 0;
    
            for (i = 1; i <= n; i++)
                for (j = 1; j <= n; j++)
                    scanf("%d", &G[i][j]);
    
            for (i = 1; i <= n; i++)
            {
                memset(vis, 0, sizeof(vis));
                if (Find(i)) ans++; ///查找元素为1的行与列的最大匹配
            }
    
            if (ans < n) printf("-1
    "); ///如果小于n则不能达到要求
            else
            {
                for (i = 1; i <= n; i++)
                {
                    while (match[i] != i)
                    {
                        no[k].x = match[i];
                        no[k++].y = match[match[i]];
                        swap(match[i], match[match[i]]); ///行和列不相等时,找到与行相等的列所匹配的行,进行交换,直到列和与其匹配的行相等
                    }
                }
    
                printf("%d
    ", k);
                for (i = 0; i < k; i++)
                    printf("R %d %d
    ", no[i].x, no[i].y);
            }
        }
    
        return 0;
    }
  • 相关阅读:
    SpringBoot中如何优雅的使用多线程
    ASP.NET MVC经典项目ProDinner项目解析(5)
    ASP.NET MVC经典项目ProDinner项目解析(4)
    ASP.NET MVC经典项目ProDinner项目解析(1)
    ASP.NET MVC经典项目ProDinner项目解析文章索引
    致我们工作中的设计模式之备忘录模式
    致我们工作中的设计模式之适配器模式
    ASP.NET MVC经典项目ProDinner项目解析(3)
    童话进行中的Silverlight
    致我们工作中的设计模式之基本原则职责单一原则
  • 原文地址:https://www.cnblogs.com/syhandll/p/4725467.html
Copyright © 2011-2022 走看看