hdoj 4619 二分图匹配

比赛的时候没有想出来怎么做,是钢牛写的,然后就下来看了一眼题解,二分图匹配,然后就写出来了。。。但是等了几天突然看到题想到的还是贪心,然后就是没有想到二分匹配上面去,以至于又想了好久好久。。。然后我自己都无语了,还是先想想贪心怎么做!!!

说下二分匹配的思路:一个格子最多可以由一个竖着的牌和一个横着的牌共同占有,我们只能选择其中的一个的,所以根据共同占有的格子数来进行建图,找到最大匹配数,最多可以放的牌就是从的牌数减去最大匹配的个数的。下面是代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<climits>
#include<map>
using namespace std;

#define rep(i,n) for(int i=0; i<(n); ++i)
#define repf(i,n,m) for(int i=(n); i<=(m); ++i)
#define repd(i,n,m) for(int i=(n); i>=(m); --i)
#define ll long long
#define inf 1000000000
#define exp 0.000000001
#define N 2010 
struct node
{
       int x1,y1,x2,y2;
       node(){};
       node(int _x1,int _y1,int _x2,int _y2):x1(_x1),y1(_y1),x2(_x2),y2(_y2){}
};
vector<node>a;
int n,m;
vector<int>vec[N];
bool vis[N];
int next[N];

bool find(node a,node b)
{
     if(a.x1==b.x1 && a.y1==b.y1) return false;
     if(a.x1==b.x2 && a.y1==b.y2) return false;
     if(a.x2==b.x1 && a.y2==b.y1) return false;
     if(a.x2==b.x2 && a.y2==b.y2) return false;
     return true;
}

bool fin(int t)
{
     rep(i,vec[t].size())
     {
          int m=vec[t][i];
          if(vis[m]==false)
          {
              vis[m]=true;
              if(next[m]==-1 || fin(next[m]))
              {
                     next[m]=t;
                     return true;
              }
          }
     }
     return false;
 }
int sum()
{
    memset(next,-1,sizeof(next));
    int m=0;
    rep(i,n)
    {
            memset(vis,false,sizeof(vis));
            if(fin(i))
            m++;
    }
    return m;
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
         if(n==0 && m==0) break;
          rep(i,n+m) vec[i].clear();
          int x,y;
          a.clear();
          int nn=0;
          repf(i,1,n)
          {
               scanf("%d%d",&x,&y);
               {
                  a.push_back(node(x,y,x+1,y));
               }
          }
          repf(i,1,m)
          {
                     scanf("%d%d",&x,&y);
                     a.push_back(node(x,y,x,y+1));
          }
          rep(i,n+m)
            repf(j,i+1,n+m-1)
             if(!find(a[i],a[j]))
        //     cout<<i<<" "<<j<<endl,
              vec[i].push_back(j);//vec[j].push_back(i);
          n=n+m;
        //  cout<<n<<endl; 
          int mm=sum();
          printf("%d\n",n-mm);
    }
    return 0;
}


你可能感兴趣的:(hdoj 4619 二分图匹配)