题意:
一个矩阵,元素除了1就是0,问将所有的在同行或者同列的1连接起来,最少需要多少条线。
输入:
2
4 4
0010
0101
0010
0000
5 4
1001
0010
1100
1110
0101
输出:
Case #1: 2
Case #2: 4
分析:
看到题目的第一眼以为是将统计每一行每一列中1的个数,之后从中依次去掉1个数最多的行,统计去几次之后再与按列去和按行去
取最小值,交了一次wa,是因为没有考虑如果碰到几行或者几列或者行列相同的个数应该怎么去,赛后看了题解知道是一个二部图
最大匹配的匈牙利算法(用于求解匹配的算法)。
代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
char c[110][110];
int vis1[110],vis2[110],n,m,k;
bool Find(int x)//固定行,递归
{
for(int j=0; j<m; j++)
{
if(c[x][j]=='1'&&!vis1[j])
{
vis1[j]=1;
if(vis2[j]==-1||Find(vis2[j]))
{
vis2[j]=x;
return true;
}
}
}
return false; //该行没有1
}
int match()
{
int cnt=0;
for(int i=0; i<n; i++)
{
memset(vis1,0,sizeof(vis1));
if(Find(i))
cnt++;
}
return cnt;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(vis2,-1,sizeof(vis2));
scanf("%d%d",&n,&m);
for(int i=0; i<n; i++)
{
scanf("%s",c[i]);
}
printf("Case #%d: %d\n", ++k,match());
}
return 0;
}