您的位置:首页 > 其它

hdu 2119 最小点覆盖

2014-03-30 11:42 274 查看
/*
题意:给出一个由0和1组成的n*m的矩阵,每一次可以删除整行或者整列的1,问最少进行多少次删除可以将所有的1删除

题解:最小点覆盖==最大匹配
关键是建图:以行号为一个点集,列号为另一点集,矩阵中为1的方格加边(i,j),建立二部图(实际上不一定要以二部图
的思路来想,可以首先只是普通的一个建图,由行点集和列点集混合组成,然后在(i,j)加边,最后求这个图的最小点覆
盖,只是可以将两个点集分开排列就形成了二部图)
*/
#include <cstdio>
#include <cstring>

#define clr(a,b) (memset(a,b,sizeof(a)))

const int N = 105;

struct edge
{
int v,next;
}E[N*N];

int EN;

int mat
,head
;
bool vis
;
int n;

void insert(int u, int v)
{
E[EN].v = v;
E[EN].next = head[u];
head[u] = EN++;
}

bool find(int t)
{
int v;
for(int i = head[t];i != -1 ;i = E[i].next) {
if(vis[ v = E[i].v ])
continue;
vis[v] = true;
if(mat[v] == -1 || find(mat[v])) {
mat[v] = t;
return true;
}
}
return false;
}
inline int MaxMatch() {
int i,num = 0;
clr(mat,-1);
for(i = 0;i < n;i ++) {
clr(vis,false);
num += find(i);
}
return num;
}

int main(void)
{
int m;
while (~scanf("%d",&n) && n)
{
scanf("%d",&m);
EN = 0;
memset(head,-1,sizeof(head));
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
{
int t;
scanf("%d",&t);
if (t)
{
insert(i,j);
}
}
printf("%d\n",MaxMatch());
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: