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. springmvc的讲解

    概述 继 Spring 2.0 对 Spring MVC 进行重大升级后,Spring 2.5 又为 Spring MVC 引入了注解驱动功能.现在你无须让 Controller 继承任何接口,无需在 ...

  2. 获取checkboxlist选中的值以及绑定来自之前选中的来自数据库的值

    //////ps:一下几句都是一个意思,为的是以后有人搜索关键字的时候能定位到这里///checkboxlist绑定选中值///checkboxlist绑定来之mssql数据的值///checkbox ...

  3. python 元类与定制元类

    1:元类 元类:类的创建与管理者 所有类的元类是type class a: pass print(type(a)) 结果:<class 'type'> 2:定制元类 类的实例化过程:(可看 ...

  4. <httpProtocol/>配置http协议头

    Web.Config中的位置 <configuration> <system.webServer> <httpProtocol> <!--http协议内容-- ...

  5. (转) 将VB.NET网站转换成C#的全过程

    在学习URL重写过程中碰到个是VB写的源码,看起来总是不爽的就GOOLE了下 感觉这个文章写的不错 原文地址 http://www.cnblogs.com/cngunner/archive/2006/ ...

  6. SQL流程控制语句学习(三):while break continue

    1.while语法 while   布尔表达式 {sql语句或语句块} break  --跳出本层循环 {sql语句或语句块} continue  --跳出本次循环 {sql语句或语句块} 2.whi ...

  7. linux一些常用指令整理

    set number:设置行号 set list:区分tab和空格 按w:一个字一个字跳转 按b:一个字一个字回跳 shift+6:行首 shift+4:行尾 ctrl+v:选中块,再按shift+i ...

  8. (原)ubuntu14.04中安装gcc4.9和g++4.9

    http://stackoverflow.com/questions/28683747/installing-gcc4-9-on-ubuntu-14-04-lts http://askubuntu.c ...

  9. C程序设计语言练习题1-8

    练习1-8 编写一个统计空格.制表符与换行符个数的程序. 代码如下: #include <stdio.h> // 包含标准库的信息. int main() // 定义名为main的函数,它 ...

  10. S3C2440的GPIO

    S3C2440一共有A B C D E F G H J 共九组IO口,一共是130个,每组IO口的个数如下图所示, 其中A组IO口只有输出功能,没有输入功能, 关于GPXCON寄存器,这个寄存器用来配 ...