Round Marriage(cf-981f)(二分,图的匹配)

该代码解决了一个来自Codeforces的竞赛问题,涉及到婚姻配对的优化。程序使用二分搜索确定最大匹配距离,其中男人的位置在不断右移以寻找与女人位置的最佳匹配。输入包括男人和女人的位置,以及一个移动距离L,目标是确保每个男人都能找到在给定范围内的伴侣。
摘要由CSDN通过智能技术生成

Problem - F - Codeforces

Round Marriage - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

二分最大的距离,对于左集合的任何一个点x,他能连边的点就是右集合中的区间[lx,rx]。x右移,对应的集合也会右移。所以左集合的任意子集,对应右集合的交集中元素个数都应该大于他。设左区间[a,b]右区间[la,Rb],那么

#include <bits/stdc++.h>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <set>
#define x first
#define y second
#define ios ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
using namespace std;

typedef pair<int,int> PII;
typedef pair<char,int> PCI;
typedef long long LL;
//typedef __int128 i128;
typedef unsigned long long ULL;
const int N=4e5+10,INF = 0x3f3f3f3f ;
const double eps = 1e-7;

LL n,L;
LL a[N],b[N * 2];

void init()
{
    cin>>n>>L;
    for(int i=1;i<=n;i++ ) 
    cin >> a[i];
    sort(a+1,a+n+1);    
    // 读入男人的位置 并排序 
    
    for(int i=n + 1;i<=n * 2 ;i++) 
    cin >> b[i];
    sort(b+1 + n ,b+n * 2+1);
    // 读入女人的位置 并排序 
    
    for(int i=1;i<=n;i++)
    b[i] = b[i + n ] - L ;
    for(int i=n*2+1;i<=3 * n; i ++ )
    b[i] = b[i-n] + L;
    
    
    
}
// 将男人的位置a 不断往右移动 找到最小的 与b的匹配值  

// L >= 2 * n
int judge(int len)
{
    int ml=-INF,mr = INF;
    
    for(int i=1;i<=n;i ++ )
    {
        int l=lower_bound(b+1,b+1+3*n,a[i]-len) - b -i;
        // l 在b 中 找到 大于等于 a[i]-len ,b[l] >= a[i] - len 
        int r=upper_bound(b+1,b+1+3*n,a[i] + len) - b- i;
        // r 在b 中 找到 大于 a[i]-len  b[r] > a[i] + len 
        --r; // b[r] <= a[i] + len   
        
        // b 在 [l,r]  中 使得  a 属于 [a[i]-len,a[i]+len] 
        ml = max(ml,l);
        mr = min(mr,r);
    }
        
    return ml <= mr;    
}



void solve()
{
    init();
    
    
    int l=0,r=L;
    while(l < r )
    {
        int mid = l + r >> 1;
        if(judge(mid)) r = mid;
        else l = mid + 1;
    }
    cout << l << endl;
        
    
}


int main()
{
//    freopen("1.txt","r",stdin);
//    ios 
    int T=1;
//     cin>>T;
    while(T -- )
    {
        solve();
    }    
    
    
    
    
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值