zoukankan      html  css  js  c++  java
  • HDU2819 Swap —— 二分图最大匹配

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

    Swap

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 4003    Accepted Submission(s): 1478
    Special Judge


    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
     
    Source
     
    Recommend
    gaojie

    题解:

    题意:给出一个大小为n*n的01矩阵,问能否通过交换行或列,使得主对角线上的数全为1?

    1.用匈牙利算法求出最大匹配数cnt,如果cnt等于n,则可以实现。

    2.可知,我们可以通过只交换行或者只交换列,就能使得主对角线上的数全为1。

    3.枚举每一行i,对于第i行,找到与第i列匹配的那一行k,然后交换第i行和第k行。这样就满足了第i行有1在对角线上。

    代码如下:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <string>
     6 #include <vector>
     7 #include <map>
     8 #include <set>
     9 #include <queue>
    10 #include <sstream>
    11 #include <algorithm>
    12 using namespace std;
    13 const int INF = 2e9;
    14 const int MOD = 1e9+7;
    15 const int MAXN = 100+10;
    16 
    17 int n;
    18 int M[MAXN][MAXN], id[MAXN][MAXN], xlink[MAXN], ylink[MAXN];
    19 bool vis[MAXN];
    20 
    21 bool dfs(int u)
    22 {
    23     for(int i = 1; i<=n; i++)
    24     if(M[u][i] && !vis[i])
    25     {
    26         vis[i] = true;
    27         if(ylink[i]==-1 || dfs(ylink[i]))
    28         {
    29             ylink[i] = u;
    30             xlink[u] = i;
    31             return true;
    32         }
    33     }
    34     return false;
    35 }
    36 
    37 int hungary()
    38 {
    39     int ret = 0;
    40     memset(xlink, -1, sizeof(xlink));
    41     memset(ylink, -1, sizeof(ylink));
    42     for(int i = 1; i<=n; i++)
    43     {
    44         memset(vis, 0, sizeof(vis));
    45         if(dfs(i)) ret++;
    46     }
    47     return ret;
    48 }
    49 
    50 int main()
    51 {
    52     while(scanf("%d", &n)!=EOF)
    53     {
    54         for(int i = 1; i<=n; i++)
    55         for(int j = 1; j<=n; j++)
    56             scanf("%d", &M[i][j]);
    57 
    58         int cnt = hungary();
    59         if(cnt<n)
    60         {
    61             printf("-1
    ");
    62             continue;
    63         }
    64 
    65         int ans = 0, op[MAXN][2];
    66         for(int i = 1; i<n; i++)
    67         for(int j = i+1; j<=n; j++)
    68         {
    69             if(xlink[j]==i)
    70             {
    71                 swap(xlink[j], xlink[i]);
    72                 op[++ans][0] = i; op[ans][1] = j;
    73                 break;
    74             }
    75         }
    76 
    77         printf("%d
    ", ans);
    78         for(int i = 1; i<=ans; i++)
    79             printf("R %d %d
    ", op[i][0], op[i][1]);
    80     }
    81 }
    View Code
  • 相关阅读:
    python数据处理——numpy_2
    Python数据处理——numpy_1
    MyEclipse 6.5 代码单词自动提示设置方法
    c语言 标准输入与输出
    JAVA中的NullPointerException异常
    c语言memmove()
    c语言 isalpha,isdigit,islower,isupper,isalnum等一系列函数
    c语言fflush()
    c语言 多维数组与指针
    c语言 回车符和换行符
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/7818268.html
Copyright © 2011-2022 走看看