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. 【转】 LINQ To SQL 语法及实例大全

    LINQ to SQL语句(1)之Where Where操作 适用场景:实现过滤,查询等功能. 说明:与SQL命令中的Where作用相似,都是起到范围限定也就是过滤作用的,而判断条件就是它后面所接的子 ...

  2. 浅谈css的预编译---less语言

    正如各位所知道的一样,css是一门标记性语言,语法相对简单,对使用者的要求也比较低 .不过可乐不知道友友们有没有发现,在使用css的时候需要书写大量看似没有逻辑的代码,不方便维护及扩展,不利于复用,尤 ...

  3. objectivc-c---block

    基本格式: returnType (^blockName[num])(paramList|void) = ^returnType(paramList|void){block Body}; 标红部分可根 ...

  4. Access中的SELECT @@IDENTITY

    在Access数据库中存在select @@identity吗?答案是肯定的.但是Access一次只能执行一条SQL,多条SQL需要多次执行,这是限制.在SQL Server中,可以一次执行多条SQL ...

  5. (搬运工)推荐!国外程序员整理的 C++ 资源大全

    标准库 C++标准库,包括了STL容器,算法和函数等. C++ Standard Library:是一系列类和函数的集合,使用核心语言编写,也是C++ISO自身标准的一部分. Standard Tem ...

  6. MFC 点击改变文本 加法计时器 伸缩窗体

    1.添加所需控件,设置ID:labNum1,txtNum1.txtNum2.txtNum3.btnAdd,并将labNum1的属性Notify->true(控件在被单击或双击时可以发送消息) 2 ...

  7. poj1127 Jack Straws(线段相交+并查集)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Jack Straws Time Limit: 1000MS   Memory L ...

  8. C++ Primer 5th 第3章 字符串、向量和数组

    *****代码在Debian g++ 5.40 / clang++ 3.8(C++11)下编写调试***** 本章主要是关于字符串.数组的内容,以及一些简单的容器知识. 1.using的声明 usin ...

  9. 使用SQL除掉文本中特殊的ascll字符比如Enter,Tab,空格键

    一.在SQL查询的字段中如果包含tab.enter.空格键,可以使用ascii码进行替换: --替换了文本中含有tab键,Enter键,空格键的ascii码 select REPLACE(REPLAC ...

  10. PHP 计算页面执行时间

    PHP 计算页面执行时间 < ?php class runtime { var $StartTime = 0; var $StopTime = 0; function get_microtime ...