/*
题意:要求放车的数目尽量多。 但是一行一列只能有一个车,所以以横坐标为一个集合,以纵坐标为另外一个集合,以输入放车
的点,连边建好图。一行一列只有一个车,正好对应二分图的匹配,一一对应,尽量多,则是求最大的匹配。
然后中要点指的是删除某个车,使得最大匹配变小,也就是删除某条边,能改变最大匹配。则这就是一个重要的点。
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<vector>
using namespace std;
#define MAX 101
int n,m,k;
int map[MAX][MAX];
int vis[MAX];
int match[MAX];
int find(int x)
{
for(int i=1;i<=m;i++)
{
if(map[x][i]!=0)
{
if(!vis[i])
{
vis[i]=1;
if(match[i]==-1||find(match[i]))
{
match[i]=x;
return 1;
}
}
}
}
return 0;
}
int main()
{ int ca=1;
while(scanf("%d %d %d",&n,&m,&k)!=EOF)
{ memset(map,0,sizeof(map));
for(int i=1;i<=k;i++)
{
int x,y;
scanf("%d %d",&x,&y);
map[x][y]=1;
}
int count=0;
memset(match,-1,sizeof(match));
for(int i=1;i<=n;i++)
{ memset(vis,0,sizeof(vis));
if(find(i)) count++;
}
int count1=0,count2;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(map[i][j]!=0)
{
map[i][j]=0;count2=0;
memset(match,-1,sizeof(match));
for(int i=1;i<=n;i++)
{
memset(vis,0,sizeof(vis));
if(find(i)) count2++;
}
map[i][j]=1;
if(count2!=count) count1++;
}
}
}
printf("Board %d have %d important blanks for %d chessmen.\n",ca++,count1,count);
}
}
hdu1281最大匹配
最新推荐文章于 2021-09-09 17:51:24 发布