zoukankan      html  css  js  c++  java
  • hdu 2819 Swap

    Swap

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 1089    Accepted Submission(s): 366
    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
     

     恶心的题

    /*
    这题要注意几个地方;
    这题可用二分匹配来做(ps:看别人题解才知道可以这么做)
    首先它是求等最大匹配
    然后就是如果这题有解,我们可以
    只通过交换行或者只通过交换列来达到要求(special judge)
    以行为一个集合,以含1的列为一个集合,用匈牙利算法进行匹配就行了
    匹配数量如果小于n就无解,否者记录路径,输出结果
    */
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    int map[105][105];
    int linky[105],vis[105];
    int n,a[105],b[105];
    int dfs(int x)
    {
         int i;
         for(i=1;i<=n;i++)
         {
              if(map[x][i]&&!vis[i])
              {
                   vis[i]=1;
                   if(linky[i]==-1||dfs(linky[i]))
                   {
                        linky[i]=x;
                        return 1;
                   }
              }
         }
         return 0;
    }
    int main()
    {
         int i,j,t;
         while(scanf("%d",&n)!=EOF)
         {
              for(i=1;i<=n;i++)
                   for(j=1;j<=n;j++)
                     scanf("%d",&map[i][j]);
              memset(linky,-1,sizeof(linky));
              int ans=0;
              for(i=1;i<=n;i++)
              {
                   memset(vis,0,sizeof(vis));
                   if(dfs(i))
                        ans++;
              }
              if(ans<n)
              {
                   printf("-1
    ");
                   continue;
              }
              int k=0;
              for(i=1;i<n;i++)//i代表的是列,目的是要使得第i列的第i个元素为1
              {
                   if(linky[i]!=i)//因为最终的目的是要使所有主对角线上的元素全为1,linky[i]记录的是匹配的行号
                   {                     //如果linky[i]和列号相等就说明该行的第i个元素为1了,否者继续往后找
                        for(j=i+1;j<=n;j++)
                        {
                             if(linky[j]==i)//行号和列号相等就找到了
                             {
                                  a[k]=i;//a,b数组记录交换次序
                                  b[k++]=j;
                                  t=linky[i];//这里交换的是列
                                  linky[i]=linky[j];
                                  linky[j]=t;
                             }
                        }
                   }
              }
              printf("%d
    ",k);
              for(i=0;i<k;i++)
                   printf("C %d %d
    ",a[i],b[i]);
         }
         return 0;
    }
  • 相关阅读:
    分页存储过程
    WinForm中DataGridView显示更新数据--人性版
    char类型的说明
    代码创建数据库_表--SqlServer数据库
    单例设计模式
    c#中的正则表达式
    sessionStorage 和 localStorage
    图片懒加载插件lazyload.js详解
    git安装加操作(转)
    php获取数据转换成json格式
  • 原文地址:https://www.cnblogs.com/llei1573/p/3272710.html
Copyright © 2011-2022 走看看