Codeforces Round #310 (Div. 2)------D(优先队列

大意:有若干岛屿分布在坐标轴上,每个岛屿给出左右边界,桥两端必须架在岛上,现在求一个方案在这些岛屿上架桥。

思路:比赛的时候abc做得好慢。。。看d的时候一下就发现是做过的题,然而没时间写(事实证明我写了1个多小时。。),对于每一个岛屿间隙,都有一个桥的可行长度范围,记为,i,r,则把桥的长度升序排列,间隙按l升序排列,然后对于每一座桥,把这座桥可以搭建的间隙全部入队,优先队列的堆顶取出的元素是r最小的元素,如果堆顶元素的r<现在的桥的长度,那么无解,否则一直继续下去,最后判断用掉的桥有多少即可。。。。这题的输出也很蛋疼,间隙和桥都要输出原来的编号。。。搞得好麻烦。。。

#include<bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;
struct STR{
    ll f,s;
    ll o;
    bool operator < (const STR &C)const{
        return s>C.s;
    }
};
bool cmp1(STR a,STR b){
    if(a.f!=b.f)
        return a.f<b.f;
    else return a.s<b.s;
}
const int maxv=2e5+40;
STR read[maxv];
struct BRI{
    ll l,o;
};
bool cmp2(BRI a,BRI b){
    return a.l<b.l; 
}
class cmp3{
    public:
        bool operator() (BRI a,BRI b){
            return a.l<b.l;
        }
};
BRI bridge[maxv];
priority_queue<STR> Q;
int n,m;
struct ANS{
    ll b,o;
};
bool cmp4(ANS a,ANS b){
    return a.o<b.o;
}
vector<ANS> ans;
int main(){
    ////freopen("/home/files/CppFiles/in","r",stdin);
    cin>>n>>m;
    for(int i=0;i<n;i++){
        cin>>read[i].f>>read[i].s;
    }
    for(int i=0;i<m;i++){
        cin>>bridge[i].l;
        bridge[i].o=i+1;
    }
    sort(bridge,bridge+m,cmp2);
    sort(read,read+n,cmp1);
    for(int i=0;i<n-1;i++){
        ll tf=read[i+1].f-read[i].s;
        ll ts=read[i+1].s-read[i].f;
        read[i].f=tf;read[i].s=ts;
        read[i].o=i;
    };
    n--;
    sort(read,read+n,cmp1);
    int h=0;
    int added=0;
    for(int i=0;i<m;i++){
        while(h<n&&bridge[i].l>=read[h].f){
            Q.push(read[h]);
            h++;
        }
        if(Q.empty()){
            continue;
        }else{
            if(Q.top().s<bridge[i].l){
                cout<<"No"<<endl;
                return 0;
            }else if(Q.top().f<=bridge[i].l){
                ans.pb((ANS){bridge[i].o,Q.top().o});
                Q.pop();
                added++;
            }
        }
    }
    if(added<n){
        cout<<"No"<<endl;
        return 0;
    }
    cout<<"Yes"<<endl;
    sort(ans.begin(),ans.end(),cmp4);
    for(int i=0;i<ans.size();i++) cout<<ans[i].b<<" ";
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/Cw-trip/p/4611950.html