zoukankan      html  css  js  c++  java
  • hdu 2819(二分图匹配)

    此题可有对角线都是1的方阵进行 行变换或列变换 得到。  

    如果这样想就可以知道, 每行只选一个列,要把所有的列全部选完, 而且最后只需进行行变换就可以转变成对角线全为一

    Swap

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 892    Accepted Submission(s): 283
    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
     
    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    using namespace std;
    #define N 110
    
    int g[N][N];
    int n;
    int mark[N],pre[N];
    
    int dfs(int s)
    {
        for(int i=1;i<=n;i++)
        {
            if(g[s][i]==0||mark[i]==1) continue;
            mark[i]=1;
            if(pre[i]==-1||dfs(pre[i]))
            {
                pre[i]=s;
                return 1;
            }
        }
        return 0;
    }
    
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            memset(g,0,sizeof(g));
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    int tmp;
                    scanf("%d",&tmp);
                    if(tmp==1)
                        g[j][i]=1;
                }
            }
            int sum=0;
            memset(pre,-1,sizeof(pre));
            for(int i=1;i<=n;i++)
            {
                memset(mark,0,sizeof(mark));
                sum+=dfs(i);
            }
            if(sum!=n) printf("-1\n");
            else
            {
                int ans[110];
                int cnt=1;
                for(int i=1;i<=n;i++)
                {
                    for(int j=i;j<=n;j++)
                    {
                        if(pre[j]==i)
                        {
                            ans[cnt++]=j;
                            swap(pre[j],pre[i]);
                            break;
                        }
                    }
                }
                printf("%d\n",n);
                for(int i=1;i<=n;i++)
                    printf("R %d %d\n",i,ans[i]);
            }
        }
        return 0;
    }
  • 相关阅读:
    selenium手机百度搜索
    selenium模拟手机浏览器
    selenium模拟登录赶集网,手动解决验证码问题
    selenium模拟登录京东,手动解决验证码问题,抓取购物车价格
    selenium模拟登录QQ空间,手动解决验证码问题
    两数之和&N数之和(求教!)
    Linux内核设计与实现——从内核出发
    Linux内核简介
    编程规范
    GIT基础使用
  • 原文地址:https://www.cnblogs.com/chenhuan001/p/3047981.html
Copyright © 2011-2022 走看看