codeforces #310 div2 D 分类: codeforces 2015-06-29 20:03 29人阅读 评论(0) 收藏


如果 Lj+1Rj<=ai<=Rj+1Lj

那么就可以在第 j 个小岛和第 j+1 个小岛之间建一座长度为 ai 的桥梁,

当然,每个桥梁只能使用一次。


很明显可以想到二分图匹配,X 侧点表示相邻小岛之间的连线,Y 侧点表示桥梁,

Lj+1Rj<=ai<=Rj+1LjG(j,i)=true

然而复杂度是 O(nm),并不能解决这个问题。


感觉还有一些有用的信息没有被用上,可以发掘区间的性质。

将相邻小岛之间的桥梁距离限制视为区间,将桥梁视为结点,

RQ(i)=Ri+1LiLQ(i)=Li+1Ri

每个区间都与满足条件最小的点匹配,并不会影响可行性。

将区间和结点都排序,贪心处理。


具体实现:

1. 以左端点为关键字,将区间排序,将结点排序。

2. 从小到大处理每个节点:

         2.1LQ(j)<=ai,将 RQ(j) 放入堆中。

         2.2 若堆不为空,取出堆顶元素 RQ(t),否则处理下一个结点。

         2.3ai<=RQ(t),将RQ(t)从堆中删除,否则无解.

3. 判断是否已经处理完所有区间,若还没有处理完所有区间则无解。

时间复杂度 O(mlog2n)


#include <cstdio>
#include <cstdlib>
#include <utility>
#include <queue>
#include <iostream>
#include <algorithm>

const int maxn = 2e5+5, maxm = maxn;

struct interval
{
    long long l, r; int id;
};

int n, m;
interval b[maxn], d[maxn];
std::pair<long long, int> a[maxm];
int ans[maxn];

typedef std::pair<long long, int> Heapnode;
#define Root_Min std::vector<Heapnode>,std::greater<Heapnode> 
std::priority_queue<Heapnode, Root_Min> heap;

template<typename LongNumber>void read(LongNumber &x)
{
    x = 0;char c = getchar();
    while(c < '0' || c > '9') {c = getchar();}
    while(c >= '0' && c <= '9')
        {x = (x<<3) + (x<<1) + (c-'0'); c = getchar();}
}
template<typename LongNumber>void write(LongNumber x)
{
    static char s[20];int sl = 0;
    while(x) s[++sl] = x%10 + '0',x /= 10;
    if(!sl) {putchar('0');return;}
    while(sl) putchar(s[sl--]);
}
bool cmp(const interval &a, const interval &b)
{
    return (a.l != b.r)?(a.l < b.l):(a.r < b.r); 
}

int main()
{
    int g = 1;
    long long scan;

#ifndef ONLINE_JUDGE    
    freopen("D.in","r",stdin);
    freopen("D.out","w",stdout);
#endif

    read(n), read(m);
    for(int i = 1; i <= n; i++)
        read(b[i].l), read(b[i].r);
    for(int i = 1; i <= m; i++)
        read(scan), a[i] = std::make_pair(scan, i);

    for(int i = 1; i < n; i++)
    {
        d[i].id = i;
        d[i].l = b[i+1].l - b[i].r;
        d[i].r = b[i+1].r - b[i].l;
    }
    std::sort(d + 1, d + n, cmp);
    std::sort(a + 1, a + m + 1); 

    for(int i = 1; i <= m; i++)
    {
//  d[g-1].l <= a[i] < d[g].l
        while(g < n && !(a[i].first < d[g].l))
            heap.push(std::make_pair(d[g].r, g)), g++;

        if(!heap.empty())
        {
            int t = heap.top().second;

            if(a[i].first <= d[t].r)
                ans[d[t].id] = a[i].second, heap.pop();
        }

    }

    if(heap.empty() && g == n)
    {
        puts("Yes");
        for(int i = 1; i < n; i++)
            write(ans[i]), putchar(' ');        
    }
    else
    {
        puts("No");
    }


#ifndef ONLINE_JUDGE
    fclose(stdin);
    fclose(stdout);
#endif
    return 0;           
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

posted @ 2015-06-29 20:03  <Dash>  阅读(164)  评论(0编辑  收藏  举报