HDU 2819 Swap 【二分图匹配 交换方法】

来源:互联网 发布:淘宝免费注册 编辑:程序博客网 时间:2024/06/05 06:20

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

题意:给出一个01矩阵,每次交换某两行或者某两列,使得最终矩阵对角线全是1,问是否可行,可行输出交换次数及方法

做法:1A好开心~~~~

这种nxn矩阵神马的很容易想到是让行作为左边,列作为右边,位置是1的连边,如果是最大匹配数是n那么可解。问题是如何交换?根据增广路的思想,我们尽量去满足匹配的要求(说是增广路有点牵强啊==)由于跑匈牙利的时候是linker[y]=x那么当我们发现有一组的linker[i]!=i时就要交换swap(linker[i],linker[linker[i]]);一直递归下去就完事了

    #include <iostream>    #include<cstdio>    #include<cstring>    #include<vector>    using namespace std;    #define M 550    #define MAXN 100    #define inf 0x3f3f3f3f    int uN,vN;//u,v数目    int g[MAXN][MAXN];    int linker[MAXN];    bool used[MAXN];    bool dfs(int u)//从左边开始找增广路径    {        int v;        for(v=0;v<vN;v++)//这个顶点编号从0开始,若要从1开始需要修改          if(g[u][v]&&!used[v])          {              used[v]=true;              if(linker[v]==-1||dfs(linker[v]))              {//找增广路,反向                  linker[v]=u;                  return true;              }          }        return false;//这个不要忘了,经常忘记这句    }    int hungary()    {       // puts("hungary");        int res=0;        int u;        memset(linker,-1,sizeof(linker));        for(u=0;u<uN;u++)        {            memset(used,0,sizeof(used));            if(dfs(u)) res++;        }        return res;    }    int t,m,n,tot;    vector< pair<int,int> >ans;    void dfs2(int x)    {        ans.push_back(make_pair(linker[x]+1,linker[linker[x]]+1));      //  printf("R %d %d\n",,);        tot++;        swap(linker[x],linker[linker[x]]);        bool exi=0;        for(int i=0;i<n;i++)        {            if(linker[i]!=i)            {                dfs2(i);                exi=1;                break;            }        }        return;    }    int main()    {       // freopen("cin.txt","r",stdin);        while(~scanf("%d",&n))        {            uN=n;            vN=n;            memset(g,0,sizeof(g));            for(int i=0;i<n;i++)            {                for(int j=0;j<n;j++)                {                    int x;                    scanf("%d",&x);                    if(x==1)g[i][j]=1;                }            }            if(hungary()!=n)puts("-1");            else            {                tot=0;                ans.clear();                for(int i=0;i<n;i++)                {                    if(linker[i]!=i)                    {                        dfs2(i);                        break;                    }                }                printf("%d\n",tot);                for(int i=0;i<ans.size();i++)                    printf("R %d %d\n",ans[i].first,ans[i].second);            }        }        return 0;    }


0 0
原创粉丝点击