zoukankan      html  css  js  c++  java
  • USACO 2017 December Contest Gold T1: A Pie for a Pie

    题目大意

    Bessie和Elsie各自烤了 N(1≤N≤10^5)个馅饼。Bessie 会这 2N 个馅饼打分,Elsie 也会。二者的打分均为一个 1e9 的非负整数。由于她们口味不同,每个派的两个分数可能不同。
    她们想互赠礼物。开始时,Bessie 送给 Elsie 一个馅饼。她们收到礼物(对方做的馅饼)后都会回赠对方一个自己做的馅饼。
    她们选择回礼的方法相同。以 Elsie 为例,Elsie 根据自己的打分来选择回礼。回礼的分数至少要大于她收到的馅饼的分数,但两个馅饼的分数差不能大于 D(0≤D≤10^9) 。如果有多个馅饼满足要求,Elsie 可以选择其中的任意一个作为回礼。

    若没有馅饼满足要求,Elsie 会放弃。Bessie 选择回礼的方法同理。
    她们之间的礼物交换将持续到一头牛放弃(Bad End),或一头牛收到一个她自己打分为 0 的馅饼,此时礼物交换愉快结束(Happy End)。
    请注意,不能把一个馅饼赠送两次,不能把馅饼送给自己。
    Bessie 想知道:对于每个她做的馅饼,如果她将这个馅饼作为最开始送给 Elsie 的礼物,她俩至少要互赠多少次馅饼(Bessie 给 Elsie 算一次,Elsie 回赠 Bessie 又算一次),才能 Happy End 。如果不可能 Happy End,请输出 -1

    题目分析

    我们要求出对于每个馅饼,都要求出最少要送多少次。而观察数据范围,显然一个一个求是不太可行的,所以考虑一次全求出来,使用最短路。

    考虑如何建边,我们应该反向建边,把每个分数0的点作为起点。建图时应对每个两人的pie分别排序,这样便于二分建图。

    (虽然此算法可能被卡成N2 的,但由于出题人都是懒的,所以可以通过)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int MAXN=400005;
     4 const int Inf=0x3f3f3f3f;
     5 struct Node{
     6     int bv,ev,id;
     7 }pb[MAXN],pe[MAXN];
     8 
     9 inline bool cmpb(Node x,Node y){
    10     return x.bv<y.bv;
    11 }
    12 inline bool cmpe(Node x,Node y){
    13     return x.ev<y.ev;
    14 }
    15 struct FboB{
    16     inline bool operator()(const Node &x,const Node &y){
    17         return x.bv<y.bv;
    18     }
    19 };
    20 struct FboE{
    21     inline bool operator()(const Node &x,const Node &y){
    22         return x.ev<y.ev;
    23     }
    24 };
    25 
    26 struct Edge{
    27     int to,nxt;
    28 }e[MAXN<<4];
    29 int cnt,head[MAXN<<1];
    30 inline void add_edge(int u,int v){
    31     e[++cnt].to=v;e[cnt].nxt=head[u];head[u]=cnt;
    32 }
    33 int n,d;
    34 queue<int> q;
    35 int dis[MAXN<<1];
    36 inline void bfs(){
    37     while(!q.empty()){
    38         int x=q.front();
    39         q.pop();
    40         for(int i=head[x],y;i;i=e[i].nxt){
    41             y=e[i].to;
    42             if(dis[y]!=-1) continue;
    43             dis[y]=dis[x]+1;
    44             q.push(y);
    45         }
    46     }
    47 }
    48 int main(){
    49     memset(dis,-1,sizeof(dis));
    50     scanf("%d%d",&n,&d);
    51     for(int i=1;i<=n;++i){
    52         scanf("%d%d",&pb[i].bv,&pb[i].ev);
    53         if(pb[i].ev==0){
    54             dis[i]=1;
    55             q.push(i);
    56         }
    57         pb[i].id=i;
    58     }
    59     for(int i=1;i<=n;++i){
    60         scanf("%d%d",&pe[i].bv,&pe[i].ev);
    61         if(pe[i].bv==0){
    62             dis[i+n]=1;
    63             q.push(i+n);
    64         }
    65         pe[i].id=i+n;
    66     }
    67     sort(pb+1,pb+n+1,cmpb);
    68     sort(pe+1,pe+n+1,cmpe);
    69     for(int i=1,pos;i<=n;++i){
    70         Node tmp;
    71         tmp.bv=pe[i].bv;
    72         tmp.ev=pe[i].bv;
    73         pos=lower_bound(pb+1,pb+n+1,tmp,FboB())-pb;
    74         for(int j=pos;j<=n;++j){
    75             if(pb[j].bv>pe[i].bv+d) break;
    76             add_edge(pb[j].id,pe[i].id);
    77         }
    78     }
    79     for(int i=1,pos;i<=n;++i){
    80         Node tmp;
    81         tmp.bv=pb[i].ev;
    82         tmp.ev=pb[i].ev;
    83         pos=lower_bound(pe+1,pe+n+1,tmp,FboE())-pe;
    84         for(int j=pos;j<=n;++j){
    85             if(pe[j].ev>pb[i].ev+d) break;
    86             add_edge(pe[j].id,pb[i].id);
    87         }
    88     }
    89     bfs();
    90     for(int i=1;i<=n;++i)
    91         printf("%d
    ",dis[i]);
    92     return 0;
    93 } 
  • 相关阅读:
    spark streaming 概述
    spark sql 的性能调优
    LeetCode 106. Construct Binary Tree from Inorder and Postorder Traversal (用中序和后序树遍历来建立二叉树)
    LeetCode 105. Construct Binary Tree from Preorder and Inorder Traversal (用先序和中序树遍历来建立二叉树)
    LeetCode 90. Subsets II (子集合之二)
    LeetCode 88. Merge Sorted Array(合并有序数组)
    LeetCode 81. Search in Rotated Sorted Array II(在旋转有序序列中搜索之二)
    LeetCode 80. Remove Duplicates from Sorted Array II (从有序序列里移除重复项之二)
    LeetCode 79. Word Search(单词搜索)
    LeetCode 78. Subsets(子集合)
  • 原文地址:https://www.cnblogs.com/LI-dox/p/11229546.html
Copyright © 2011-2022 走看看