HDU 2819 隐式二分图匹配

http://acm.hdu.edu.cn/showproblem.php?pid=2819

这道题乍一看是矩阵变换题,估计用矩阵之类的也可以做

但是分析一下就可以知道

要凑成对角线都是1,题目允许行变换和列变换

然而观察可以得知如果可以完成只需要行变换或者列变换之一即可

donser[i][j]=1表示i,j位置有1,那么只需要变换j到i(即交换i,j行)

输出中间过程用queue

加上dfs遍历即可

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
int donser[1002][1002];
bool used[1002];
int leave[1002],a[1002],b[1002];
int M,num,abc,j;
queue<int >que;
void swap(int i,int j)
{
    int t=leave[i];leave[i]=leave[j];leave[j]=t;
}
int dfs(int x)
{
    for(int i=1;i<=M;i++)
    {
        if(donser[x][i]&&!used[i])
        {
            used[i]=true;
            if(!leave[i]||dfs(leave[i]))
            {
                leave[i]=x;
                return 1;
            }

        }
    }
    return 0;
}
int main()
{
    while(~scanf("%d",&M))
    {
        memset(donser,0,sizeof(donser));
        memset(leave,0,sizeof(leave));
        for(int i=1;i<=M;i++)
        {
            for(j=1;j<=M;j++)
            {
                scanf("%d",&num);
                if(num) {donser[i][j]=1;}
            }
        }
        num=abc=0;
        for(int i=1;i<=M;i++)
        {
            memset(used,0,sizeof(used));
            if(dfs(i)){abc++;}
        }
        if(abc!=M) {cout<<"-1"<<endl;continue;}
        abc=0,j=1;
        for(int i=1;i<=M;i++)
        {
            for(j=1;j<=M && leave[j]!=i ;j++);
            if(i!=j)
            {
                abc++;
                que.push(i);
                que.push(j);
                swap(i,j);
            }
        }
        cout<<abc<<endl;
        while(!que.empty())
        {
            cout<<"C "<<que.front();
            que.pop();
            cout<<" "<<que.front()<<endl;
            que.pop();
        }
        abc=0;
    }
    return 0;
}
时间: 2024-08-20 00:03:13

HDU 2819 隐式二分图匹配的相关文章

hdu 2819 Swap(二分图匹配)

hdu 2819 Swap 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 li

HDU 1083 网络流之二分图匹配

http://acm.hdu.edu.cn/showproblem.php?pid=1083 二分图匹配用得很多 这道题只需要简化的二分匹配 #include<iostream> #include<cstdio> #include<cstring> #define maxm 410 using namespace std; int p,n; int master[maxm]; int linking[maxm][maxm]; int has[maxm]; int sol

hdu 5943(素数间隔+二分图匹配)

Kingdom of Obsession Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 200    Accepted Submission(s): 64 Problem Description There is a kindom of obsession, so people in this kingdom do things ver

hdu 5093 Battle ships 二分图匹配

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5093 一开始就往贪心的方向想了结果wa全场 这种矩阵形式的图一般要联想到行和列构成了二分图 然后实质就是求一个最大匹配 中间的冰山实际上就是把一行或一列切成多个顶点而已 所以一开始预处理一下 然后就可以套用模板 #include <cstring> #include <cstdlib> #include <cstring> #include <cmath> #i

hdu - 1150 Machine Schedule (二分图匹配最小点覆盖)

http://acm.hdu.edu.cn/showproblem.php?pid=1150 有两种机器,A机器有n种模式,B机器有m种模式,现在有k个任务需要执行,没切换一个任务机器就需要重启一次, 如果任务i在机器A上执行,A机器需要一个对应的模式A,如果在机器B上执行,机器A需要一个模式B. 一直就是机器A在切换模式,现在让你安排一种合理的任务执行顺序,让机器重启次数最少. 每个任务之间连一条边.二分图的最小顶点覆盖就是求最少的点可以连接所有的边,然后转化成最大匹配即可. 这题就是初始状态

HDU - 2819 Swap(二分匹配)

题意:交换任意两行或两列,使主对角线全为1. 分析: 1.主对角线都为1,可知最终,第一行与第一列匹配,第二行与第二列匹配,……. 2.根据初始给定的矩阵,若Aij = 1,则说明第i行与第j列匹配,据此求最大匹配数cnt,若cnt==N,才可通过交换使主对角线都为1. 3.交换时,可只交换行或只交换列.如:只交换列,行不变(顺序为1,2,3,……,n),那么对于列,只需要根据选择排序,将每行一开始匹配的列的顺序最终也变成1,2,3,……,n即可,因为是选择排序,每次选择第i小的交换到第i个位置

hdu 1150 Machine Schedule (二分图匹配)

#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int n,m,k; int mat[110][110]; int link[110]; int vis[110]; bool find(int u) { int v; for(v=0;v<m;j++) if(g[u][v]&&!vis[v]) {

E - Swap - hdu 2819(简单二分图匹配)

题意:如果可以交换行列,问主对角线能不能全为1 分析:要想主对角线全为1很明显要有N个行列不想同的点就行了,可以用二分图匹配计算出来多能有几个.如果小与N就不能.输出要是对的就行,不必和答案一样 ************************************************************************ #include<stdio.h>#include<algorithm>#include<string.h>using namesp

HDU 3081:Marriage Match II(二分图匹配+并查集)

http://acm.hdu.edu.cn/showproblem.php?pid=3081 题意:有n个男生n个女生,他们只有没有争吵或者女生a与男生A没有争吵,且女生b与女生a是朋友,因此女生b也可以和男生A过家家(具有传递性).给出m个关系,代表女生a和男生b没有争吵过.给出k个关系,代表女生a与女生b是好朋友.每一轮过家家之后,女生只能选择可以选择并且没选过的男生过家家,问游戏能进行几轮. 思路:因为n<=100,因此支持O(n^3)的算法,挺容易想到是一个二分图匹配的.(出现在我的网络