Warm up 2

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

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 3
0 0
0 3
0 1
1 1
1 3
4 5
0 1
0 2
3 1
2 2
0 0
1 0
2 0
4 1
3 2
0 0
 
Sample Output
4
6
 
Source
 
Recommend
zhuyuanchen520
 

题解:
原来是我建图不会建。。。果然是基础功不扎实啊。。

原来就是个普通的最大独立集。  最大独立集的定义就是所选取的点集合中,任意两条边都不相连。 又因为题目中说横着的不会跟横着的相连,竖着的不会跟竖着的相连,所以。这是个相当标准的二分图。就是求X集合跟Y集合的最大独立集。    

建造图时,X取的是那0到n-1个骨牌   Y取的是后面的0到m-1个骨牌。。。无语撒。。原来当初我2分图完全弄错了。。

这题解法好像很多。。什么搜索,贪心。。不说了。。。牢记不会建图的教训。。

我提供下我写的3份模板代码吧。。。。

第一份 33MS
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cstring>
const int maxn=1111;
int g[maxn][maxn];
int cx[maxn],cy[maxn],vst[maxn];
int nx,ny;
int findpath(int u){
for(int v=0;v<ny;v++){
if(!vst[v]&&g[u][v]){
vst[v]=1;
if(cy[v]==-1||findpath(cy[v])){
cy[v]=u,cx[u]=v;
return 1;
}
}
}
return 0;
}
int MaxMatch(){
int ret=0;
memset(cx,-1,sizeof(cx));
memset(cy,-1,sizeof(cy));
for(int i=0;i<nx;i++)
if(cx[i]==-1){
memset(vst,0,sizeof(vst));
if(findpath(i))
ret++;
}
return ret;
}
struct node{
int x,y;
}mx[maxn],my[maxn];
int main(){
//freopen("1009.in","r",stdin);
int n,m;
while(scanf("%d %d",&n,&m)&&n+m){
for(int i=0,a,b;i<n;i++){
scanf("%d %d",&a,&b);
mx[i].x=a,mx[i].y=b;
}
for(int i=0,a,b;i<m;i++){
scanf("%d %d",&a,&b);
my[i].x=a,my[i].y=b;
}
memset(g,0,sizeof(g));
for(int i=0,x1,y1;i<n;i++){
x1=mx[i].x,y1=mx[i].y;
for(int j=0,x2,y2;j<m;j++){
x2=my[j].x,y2=my[j].y;
if(x1==x2&&y1==y2
||x1==x2&&y1==y2+1
||x1+1==x2&&y1==y2
||x1+1==x2&&y1==y2+1)
g[i][j]=1;
}
}
nx=n,ny=m;
printf("%d\n",n+m-MaxMatch());
}
return 0;
}

第2份:15MS

#include <cstdlib>
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#define clr(x,k) memset((x),(k),sizeof(x))
#define foreach(it,c) for(vi::iterator it = (c).begin();it != (c).end();++it)
using namespace std;
typedef vector<int> vi; const int maxn=1000;
vector<int> gx[maxn];
int cx[maxn],cy[maxn],vst[maxn];
int nx,ny;
int findpath_Vector(int u){
foreach(it,gx[u]){
if(!vst[*it]){
vst[*it]=1;
if(cy[*it]==-1||findpath_Vector(cy[*it])){
cx[u]=*it;
cy[*it]=u;
return 1;
}
}
}
return 0;
}
int maxMatch_Vector(){
int ret=0;
clr(cx,-1),clr(cy,-1);
for(int i=0;i<nx;i++)
if(cx[i]==-1){
clr(vst,0);
if(findpath_Vector(i))
ret++;
}
return ret;
}
struct node{
int x,y;
}mx[maxn],my[maxn];
int main(){
// freopen("1009.in","r",stdin);
int n,m;
while(scanf("%d %d",&n,&m)&&n+m){
for(int i=0,a,b;i<n;i++){
scanf("%d %d",&a,&b);
mx[i].x=a,mx[i].y=b;
}
for(int i=0,a,b;i<m;i++){
scanf("%d %d",&a,&b);
my[i].x=a,my[i].y=b;
}
for(int i=0;i<n;i++)
gx[i].clear();
for(int i=0,x1,y1;i<n;i++){
x1=mx[i].x,y1=mx[i].y;
for(int j=0,x2,y2;j<m;j++){
x2=my[j].x,y2=my[j].y;
if(x1==x2&&y1==y2
||x1==x2&&y1==y2+1
||x1+1==x2&&y1==y2
||x1+1==x2&&y1==y2+1)
gx[i].push_back(j);
}
} nx=n,ny=m;
printf("%d\n",n+m-maxMatch_Vector());
}
return 0;
}

第3份 15MS。  hy这个算法应该会快点的。可能是因为题目有点特殊,没有体现。

#include <cstdlib>
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
#include <iostream>
#define clr(x,k) memset((x),(k),sizeof(x))
#define foreach(it,c) for(vi::iterator it = (c).begin();it != (c).end();++it)
using namespace std;
typedef vector<int> vi; const int INF=1<<28;
const int maxn=1000;
int cx[maxn],cy[maxn];
vi gx[maxn];
int dx[maxn],dy[maxn];
int dis,nx;
int vst[maxn];
bool searchpath(){
queue<int> Q;
dis=INF;
clr(dx,-1),clr(dy,-1);
for(int i=0;i<nx;i++){
if(cx[i]==-1)
Q.push(i),dx[i]=0;
}
while(!Q.empty()){
int u=Q.front();Q.pop();
if(dx[u]>dis) break;
foreach(it,gx[u])
if(dy[*it]==-1){
dy[*it]=dx[u]+1;
if(cy[*it]==-1) dis=dy[*it];
else{
dx[cy[*it]]=dy[*it]+1;
Q.push(cy[*it]);
}
}
}
return dis!=INF;
}
int hop_Findpath_Vector(int u){
foreach(it,gx[u]){
if(!vst[*it]&&dy[*it]==dx[u]+1){//说明这是一条增广路径。但还需判断
vst[*it]=1;
if(cy[*it]!=-1&&dy[*it]==dis) //出现这种情况。说明不是增广路, 因为最后一条增路是 cy[v]==-1&&dy[v]==dis
continue;
if(cy[*it]==-1||hop_Findpath_Vector(cy[*it])){
cy[*it]=u,cx[u]=*it;
return 1;
}
}
}
return 0;
}
int hopcroft_MaxMatch_Vector(){
int res=0;
clr(cx,-1),clr(cy,-1);
while(searchpath()){
clr(vst,0);
for(int i=0;i<nx;i++){
if(cx[i]==-1){
res+=hop_Findpath_Vector(i);
}
}
}
return res;
}
struct node{
int x,y;
}mx[maxn],my[maxn];
int main(){
//freopen("1009.in","r",stdin);
int n,m;
while(scanf("%d %d",&n,&m)&&n+m){
for(int i=0,a,b;i<n;i++){
scanf("%d %d",&a,&b);
mx[i].x=a,mx[i].y=b;
}
for(int i=0,a,b;i<m;i++){
scanf("%d %d",&a,&b);
my[i].x=a,my[i].y=b;
}
for(int i=0;i<n;i++)
gx[i].clear();
for(int i=0,x1,y1;i<n;i++){
x1=mx[i].x,y1=mx[i].y;
for(int j=0,x2,y2;j<m;j++){
x2=my[j].x,y2=my[j].y;
if(x1==x2&&y1==y2
||x1==x2&&y1==y2+1
||x1+1==x2&&y1==y2
||x1+1==x2&&y1==y2+1)
gx[i].push_back(j);
}
} nx=n;
printf("%d\n",n+m-hopcroft_MaxMatch_Vector());
}
return 0;
}
如果要达到0MS的话。估计要贪心一下了。

HDU 多校联合练习赛2 Warm up 2 二分图匹配的更多相关文章

  1. HDU 1045 Fire Net 【连通块的压缩 二分图匹配】

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit: 2000/1000 MS (Java/Others)    ...

  2. 2013多校联合2 I Warm up 2(hdu 4619)

    Warm up 2 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total ...

  3. HDU 多校联合 6033 6043

    http://acm.hdu.edu.cn/showproblem.php?pid=6033 Add More Zero Time Limit: 2000/1000 MS (Java/Others)  ...

  4. 多校联合练习赛1 Problem1005 Deque LIS+LDS 再加一系列优化

    Deque Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Subm ...

  5. HDU 多校联合 6045

    Is Derek lying? Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)T ...

  6. hdu 4619 Warm up 2 二分图匹配

    题目链接 给两种长方形, 水平的和垂直的, 大小都为1*2, n个水平的, m个垂直的, 给出它们的坐标. 水平的和垂直的可以相互覆盖, 但是同种类型的没有覆盖. 去掉一些长方形, 使得剩下的全部都没 ...

  7. hdu 3861 The King’s Problem trajan缩点+二分图匹配

    The King’s Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  8. hdu 2063 二分图匹配

    题意:一些女的和一些男的有好感,有好感的能一起坐过山车,问最多能组成多少对 hdu 11 页上少有的算法题,二分图匹配问题,匈牙利算法,对于每一个汉子,看和他有好感的妹子有没有配对了,没有配对过就可以 ...

  9. hdu 5288||2015多校联合第一场1001题

    pid=5288">http://acm.hdu.edu.cn/showproblem.php?pid=5288 Problem Description OO has got a ar ...

随机推荐

  1. 一步步启动linux

    可以一步一步启动linux. 在Ubantu刚一启动时,按c健即进入Grub>提示符状态,在此状态下输入(我用的是Ubuntu 13) grub>linux /vmlinuz grub&g ...

  2. 查看Linux相关信息

    1."uname -a ",可显示电脑以及操作系统的相关信息. 2."cat /proc/version",说明正在运行的内核版本. 3."cat / ...

  3. JS 匿名函数

    一.声明: 1. 正常函数声明: //正常函数声明 function foo(p1, p2){ return p1+p2; } 2. 匿名函数声明: //匿名函数声明 var foo= functio ...

  4. 神经网络作业: NN LEARNING Coursera Machine Learning(Andrew Ng) WEEK 5

    在WEEK 5中,作业要求完成通过神经网络(NN)实现多分类的逻辑回归(MULTI-CLASS LOGISTIC REGRESSION)的监督学习(SUOERVISED LEARNING)来识别阿拉伯 ...

  5. C# 汉子增加UTF-8头

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Conv ...

  6. js ||与&&

    ||:找到结果为true的分项就停止,并返回该分项的值,否则继续执行,如果都没有为true的分项则返回最后分项的值(注意每个分项先转成bool与true进行比较). //例如下面的例子: // &qu ...

  7. Jquery简略API使用

    都是个人随手笔记,既然开通了博客园就分享给大家.谨做为参考,具体大家自己测试以及使用 ★ $() ★ JQ的一个万能获取对象的函数(获取跟CSS获取元素是一样的)$(function(){}); 替代 ...

  8. QQ在线客服

    css代码: .float0831 { POSITION: fixed; TOP: 180px; RIGHT: 1px; _position: absolute } .float0831 A { CO ...

  9. “#ifdef __cplusplus extern "C" { #endif”的定义

    平时我们在linux c平台开发的时候,引用了一些Cpp或者C的代码库,发现一些头文件有如下代码条件编译. #ifdef __cplusplus extern "C" { #end ...

  10. HTML&CSS基础学习笔记1.16-单元格间距和表格主体

    上一篇讲html学习笔记,讲过了合并单元格,那么今天就来介绍下如何控制单元格的间距,以及表格主体的相关知识. 单元格间距 在上个知识点的显示结果中你可能发现了,单元格与单元格之间有一小段空白.这是由& ...