hdu4619 Warm up 2 二分图 最大匹配

来源:互联网 发布:淘宝网英雄联盟代练 编辑:程序博客网 时间:2024/05/18 01:12

Warm up 2

Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 1325 Accepted Submission(s): 583


Problem Description
  Some 1×2 dominoes are placed on a plane. Each dominoe is placed either horizontally or vertically. It's guaranteed the dominoes in the same direction are not overlapped, but horizontal and vertical dominoes may overlap with each other. You task is to remove some dominoes, so that the remaining dominoes do not overlap with each other. Now, tell me the maximum number of dominoes left on the board.

Input
  There are multiple input cases.
  The first line of each case are 2 integers: n(1 <= n <= 1000), m(1 <= m <= 1000), indicating the number of horizontal and vertical dominoes.
Then n lines follow, each line contains 2 integers x (0 <= x <= 100) and y (0 <= y <= 100), indicating the position of a horizontal dominoe. The dominoe occupies the grids of (x, y) and (x + 1, y).
  Then m lines follow, each line contains 2 integers x (0 <= x <= 100) and y (0 <= y <= 100), indicating the position of a horizontal dominoe. The dominoe occupies the grids of (x, y) and (x, y + 1).
  Input ends with n = 0 and m = 0.

Output
  For each test case, output the maximum number of remaining dominoes in a line.

Sample Input
2 30 00 30 11 11 34 50 10 23 12 20 01 02 04 13 20 0

Sample Output
46

Source
2013 Multi-University Training Contest 2

Recommend
zhuyuanchen520
最大二分匹配,其实,我们把横着的和竖着的分成两个点集,如果两个点相交,就连一条边,我们找到最大匹配,然后,用总点数减去匹配的,就是孤立的点了,这样,就可以得出答案了!
#include <iostream>#include <stdio.h>#include <math.h>#include <string.h>using namespace std;#define MAXN 1005struct node {    int x,y;}p[MAXN][2];bool g[MAXN][MAXN];int uN,vN;int xM[MAXN],yM[MAXN];bool chk[MAXN];bool can(int i,int j){    if(p[i][0].x==p[j][1].x&&(p[j][1].y+1==p[i][0].y))    return true;    if(p[i][0].x==p[j][1].x&&(p[j][1].y-p[i][0].y==0))    return true;    if(p[i][0].x+1==p[j][1].x&&(p[j][1].y+1==p[i][0].y))    return true;    if(p[i][0].x+1==p[j][1].x&&(p[j][1].y-p[i][0].y==0))    return true;    return false;}bool SearchPath(int u){    int v;    for(v=0;v<vN;v++)    if(g[u][v]&&!chk[v])    {        chk[v]=true;        if(yM[v]==-1||SearchPath(yM[v]))        {            yM[v]=u;xM[u]=v;            return true;        }    }    return false;}int MaxMatch(){    int u,ret=0;    memset(xM,-1,sizeof(xM));    memset(yM,-1,sizeof(yM));    for(u=0;u<uN;u++)    if(xM[u]==-1)    {        memset(chk,false,sizeof(chk));        if(SearchPath(u))ret++;    }    return ret;}int main(){    int n,m,i,x,y,j;    while(scanf("%d%d",&n,&m)!=EOF&&n+m)    {       memset(g,false,sizeof(g));        for(i=0;i<n;i++)            scanf("%d%d",&p[i][0].x,&p[i][0].y);        for(i=0;i<m;i++)            scanf("%d%d",&p[i][1].x,&p[i][1].y);        for(i=0;i<n;i++)            for(j=0;j<m;j++)            if(can(i,j))            {                g[i][j]=true;            }        uN=n,vN=m;        printf("%d\n",n+m-MaxMatch());    }    return 0;}