HDU 多校联合练习赛2 Warm up 2 二分图匹配
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
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.
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
6
#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;
}
HDU 多校联合练习赛2 Warm up 2 二分图匹配的更多相关文章
- HDU 1045 Fire Net 【连通块的压缩 二分图匹配】
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit: 2000/1000 MS (Java/Others) ...
- 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 ...
- HDU 多校联合 6033 6043
http://acm.hdu.edu.cn/showproblem.php?pid=6033 Add More Zero Time Limit: 2000/1000 MS (Java/Others) ...
- 多校联合练习赛1 Problem1005 Deque LIS+LDS 再加一系列优化
Deque Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Subm ...
- HDU 多校联合 6045
Is Derek lying? Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)T ...
- hdu 4619 Warm up 2 二分图匹配
题目链接 给两种长方形, 水平的和垂直的, 大小都为1*2, n个水平的, m个垂直的, 给出它们的坐标. 水平的和垂直的可以相互覆盖, 但是同种类型的没有覆盖. 去掉一些长方形, 使得剩下的全部都没 ...
- 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 ...
- hdu 2063 二分图匹配
题意:一些女的和一些男的有好感,有好感的能一起坐过山车,问最多能组成多少对 hdu 11 页上少有的算法题,二分图匹配问题,匈牙利算法,对于每一个汉子,看和他有好感的妹子有没有配对了,没有配对过就可以 ...
- hdu 5288||2015多校联合第一场1001题
pid=5288">http://acm.hdu.edu.cn/showproblem.php?pid=5288 Problem Description OO has got a ar ...
随机推荐
- ibatis中的resultClass,parameterClass,resultMap,resultType的使用与区别
parameterClass 是参数类.指定了参数的完整类名(包括包路径).可通过别名避免每次重复书写冗长的类名. resultClass 是结果类, 二.resultClass取值 1.result ...
- CSS3新特性(阴影、动画、渐变、变形、伪元素等) CSS3与页面布局学习总结——CSS3新特性(阴影、动画、渐变、变形、伪元素等)
目录 一.阴影 1.1.文字阴影 1.2.盒子阴影 二.背景 2.1.背景图像尺寸 2.2.背景图像显示的原点 三.伪元素 3.1.before 3.2.after 3.3.清除浮动 四.圆角与边 ...
- WPF单线程定时器 简单实例
//窗体加载完毕 void MyMessageBox_Loaded(object sender, RoutedEventArgs e) { //启动定时期倒计时,多线程计时 //System.Thre ...
- arcgis engine - 命令和工具
在engine中, 命令是实现了 ICommand,我们可以通过使用 UID, progID 或 ICommand 将一个命令宿主到 ToolBarControl中. ICommand接口有一个 On ...
- c标签的使用方法
1. c:forEach <c:forEach items="> 注意varStatus相当于for循环计数器,从1开始,用${varStatus.count}获得计数器的值.而 ...
- 贪心 CF 332 C 好题 赞
题目链接: http://codeforces.com/problemset/problem/332/C 题目意思: 有n个命令,要通过p个,某主席要在通过的p个中选择k个接受. 每个任务有两个值ai ...
- js拖动层
模仿网易彩票网(http://caipiao.163.com/)的登陆框自己做了一个拖动层,不过有点小问题——在谷歌浏览拖动的时候鼠标状态变成了文字状态(cursor:text;) <!DOCT ...
- python学习第九天 -- 列表生产式
说说python特有的列表生成式.python的列表的生成式主要用法是什么? 用法就是可以使用简洁的代码生成出list集合. 直接用代码举了例子: 利用列表生成式生成列表[1x2,3x4,5x6,7x ...
- Python Udp Socket
socket(套接字),传输层通信的端点,由IP和端口号组成(IP,Port),可以通过socket精确地找到服务器上的进程并与之通信 python2.6实现,基于AF_INET(网络套接字) 类型S ...
- log4Net使用的四个步骤
第一步.引入程序集,并建立配置文件,放在根目录下config文件夹里.配置文件如下: <?xml version="1.0" encoding="utf-8&quo ...