HDU2819 Swap

来源:互联网 发布:网络管理规章制度 编辑:程序博客网 时间:2024/05/23 20:12

Swap

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4036    Accepted Submission(s): 1493
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
20 11 021 01 0
 

Sample Output
1R 1 2-1
 
题意:给你一个由0和1组成的图让你通过交换行或者列使得这张图主对角线都为1,不过不可以的话输出-1,可以的话输出交换几次,并且输出交换的方法。(因为交换方法很多,输出一组即可)
理性地想一下可以的情况,每行每列都要有个1,任意两行或者两列不能出现多个1。并且通过行交换出来的图,用列或者行列并用也可以交换出来。
至于为什么要用二分图,我认为用二分图一是好判断是不是可以变成主对角线为1的图,二是可以写出交换方法。
我们把行当做一个图,1所在的列当做另一个图,这样一来1所在的行列也就是1的坐标就是连线方式,x代表行,y代表列。当最大匹配等于n时就代表可以换成要求的图。
#include<stdio.h>#include<string.h>#include<algorithm>#include<queue>using namespace std;int n;int mapp[105][105],used[105],pp[105];int st[105],ed[105];int found(int x){    for(int i=1;i<=n;i++)    {        if(mapp[x][i]&&!used[i])        {            used[i]=1;            if(!pp[i]||found(pp[i]))            {                pp[i]=x;                return 1;            }        }    }    return 0;}int aa(){    int sum=0;    memset(pp,0,sizeof(pp));    for(int i=1;i<=n;i++)    {        memset(used,0,sizeof(used));        if(found(i))sum++;    }    return sum;}int main(){    while(~scanf("%d",&n))    {        for(int i=1;i<=n;i++)            for(int j=1;j<=n;j++)            scanf("%d",&mapp[i][j]);        int ans=aa();        if(ans!=n)        {            printf("-1\n");        }        else        {            int ans=0;            for(int i=1;i<=n;i++)//从行找起            {                if(i!=pp[i])//如果行号不对应列号                {                    for(int j=1;j<=n;j++)//去列号里边找                    {                        if(i==pp[j])//从列里找到相同的                        {                            st[ans]=i;//记录                            ed[ans]=j;                            ans++;                            swap(pp[i],pp[j]);//交换列                            break;                        }                    }                }            }            printf("%d\n",ans);            for(int i=0;i<ans;i++)            {                printf("C %d %d\n",st[i],ed[i]);            }        }    }}



原创粉丝点击