poj 3565 ants

/*
poj 3565 递归分治
还有用KM的做法
这里写的分治 按紫书上的方法
不过那里说的有点冗杂了
可以简化一下 
首先为啥可以分治 也就是分成子问题解决
只要有一个集合 黑白的个数相等 就一定能一一匹配
这个应该比较明显
因为是special judge 
所以我们只要保证每次处理的集合黑白相等就好了 
关键是怎么分
我们找到最下最左的点 作为基点 
然后将其他的按照连线与横坐标夹角的大小排序
这样就相当于那个线逆时针扫一遍 
当扫过去的黑白相等(都为0也可以)并且当前这个可以和基点不同色
也就是他俩能匹配 那显然当前这三部分 (扫过去的 没扫的 还有这条线)
都满足黑白相等 也就是说都能独立的匹配
然后分治就好了 
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define maxn 210
using namespace std;
int n,match[maxn];
struct node{
    int x,y,c,v;
}p[maxn],bas;
int cmp1(const node &a,const node &b){
    return (a.y==b.y&&a.x<b.x)||a.y<b.y;
}
int cmp2(const node &a,const node &b){
    double A=atan2(double(a.y-bas.y),double(a.x-bas.x));
    double B=atan2(double(b.y-bas.y),double(b.x-bas.x));
    return A<B;
}
void Dfs(int l,int r){
    if(l>r)return;
    sort(p+l,p+r+1,cmp1);
    bas=p[l];
    sort(p+l+1,p+r+1,cmp2);
    int s1=0,s2=0,k=l+1;
    while(s1!=s2||p[k].c==bas.c){
        if(p[k].c==bas.c)s1++;
        else s2++;k++;
    }
    if(bas.c==1)match[bas.v]=p[k].v;
    else match[p[k].v]=bas.v;
    Dfs(l+1,k-1);Dfs(k+1,r);
}
int main()
{
    scanf("%d",&n);
    memset(match,0,sizeof(match));
    for(int i=1;i<=n;i++){
        scanf("%d%d",&p[i].x,&p[i].y);
        p[i].c=1;p[i].v=i;
    }
    for(int i=1+n;i<=n+n;i++){
        scanf("%d%d",&p[i].x,&p[i].y);
        p[i].c=2;p[i].v=i-n;
    }
    Dfs(1,n+n);
    for(int i=1;i<=n;i++)
        printf("%d\n",match[i]);
    return 0;
}

 

转载于:https://www.cnblogs.com/yanlifneg/p/5974290.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值