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\n",dis[i]);
92     return 0;
93 } 

原文地址:https://www.cnblogs.com/LI-dox/p/11229546.html

时间: 2024-10-02 01:23:46

USACO 2017 December Contest Gold T1: A Pie for a Pie的相关文章

USACO 2016 December Contest Gold T1: Moocast

题目大意 FJ的N头牛(1≤N≤1000)为了在他们之间传播信息, 想要组织一个"哞哞广播"系统. 奶牛们决定去用步话机装备自己而不是在很远的距离之外互相哞哞叫, 所以每一头奶牛都必须有一个步话机. 这些步话机都有一个限制传播半径, 但是奶牛们可以间接地通过中间奶牛传播信息, 所以并不是每头牛都必须直接向其他每一头奶牛连边. 奶牛们需要去决定多少钱花在步话机上, 如果他们花了$X, 那么他们都将会得到sqrt(x)距离的步话机. 所以, 两头牛之间的欧几里得距离平方最多是X. 请帮助奶

USACO 2016 December Contest Gold T3: Lasers and Mirrors

题目大意 出于某种原因,农夫约翰的牛总是在举行激光表演. 对于他们的最新展会,奶牛已经购买了一个大功率的激光器 - 这么大,事实上,他们似乎不能轻易地从它交付的位置移动.他们想以某种方式将激光的光发送到FJ物业另一侧的谷仓.激光器和谷仓都可以被认为位于FJ农场的地图上的2D平面中的点上.牛计划指挥激光器,使得它发出水平或竖直(即,与x或y轴平行)的光束.他们会将这个光束从一些镜子反射回去,直接到谷仓. 在农场上有N个栅栏(1≤N≤100,000),位于不同的二维点(也不同于激光和谷仓),牛可以安

USACO 2017 December Contest Platinum T2: Push a Box

题目大意 一个谷仓是一个N*M的矩形网格,有一些网格里有干草.Bessie站在其中一个格子内,还有一个格子里有一个大木箱.Bessie不能和大木箱在一个格子里,也不能和干草在一个格子里. 如果她不与干草一个格子,她就可以往自己旁边的四个方向(东西南北)移动,如果她想移动到有木箱的格子里,那个木箱就会被她推一格(只要木箱的那个方向还有空间),如果没有空间,那Bessie就不能移动了. 给你谷仓的布局(空格子,干草以及木箱位置)以及Bessie的出发位置和箱子要被推到的位置,请你帮忙计算Bessie

USACO 2017 December Contest Platinum T3: Greedy Gift Takers

题目大意 有 N(1≤N≤1e5)头牛按顺序排成一列,编号从 1 到 N,1 号牛在队头,N 号牛在队尾. 每次位于队头的牛 i 拿到一个礼物,然后插入到从队尾数ci?头牛之前的位置..举个栗子: 初始队列 1,2,3,4,5 c1?= 2,c2? = 3,则第一次操作后的序列为 2,3,1,4,5,第二次操作后的序列为 3,2,1,4,5.重复无限次操作,求最后有几头牛拿不到礼物. 题目分析 一上来有个显然的结论,若一个人得不到礼物那么原序列中在他后面的人肯定也得不到礼物,因为后面的人跳不到前

USACO 2007 December Contest, Silver Problem 2. Building Roads Kruskal最小生成树算法

PROBLEM: (ENGLISH VERSION) Farmer John had just acquired several new farms! He wants to connect the farms with roads so that he can travel from any farm to any other farm via a sequence of roads; roads already connect some of the farms. Each of the N

USACO 2015 February Contest Gold T2: Censoring

题目大意 FJ把杂志上所有的文章摘抄了下来并把它变成了一个长度不超过10^5的字符串S.他有一个包含n个单词的列表,列表里的n个单词记为t1...tN.他希望从S中删除这些单词. FJ每次在S中找到最早出现的列表中的单词(最早出现指该单词的开始位置最小),然后从S中删除这个单词.他重复这个操作直到S中没有列表里的单词为止.注意删除一个单词后可能会导致S中出现另一个列表中的单词 FJ注意到列表中的单词不会出现一个单词是另一个单词子串的情况,这意味着每个列表中的单词在S中出现的开始位置是互不相同的

USACO 2018 December Contest Platinum T2: Sort It Out

题目大意 FJ有 N(1≤N≤1e5 )头奶牛(分别用 1…N 编号)排成一行.FJ喜欢他的奶牛以升序排列,不幸的是现在她们的顺序被打乱了.在过去FJ曾经使用一些诸如“冒泡排序”的开创性的算法来使他的奶牛排好序,但今天他想偷个懒.取而代之,他会每次对着一头奶牛叫道“按顺序排好”.当一头奶牛被叫到的时候,她会确保自己在队伍中的顺序是正确的(从她的角度看来).当有一头紧接在她右边的奶牛的编号比她小,她们就交换位置.然后,当有一头紧接在她左边的奶牛的编号比她大,她们就交换位置.这样这头奶牛就完成了“按

USACO 2019 February Contest Platinum T1: Cow Dating

题目大意 由于目前可供奶牛们使用的约会网站并没有给Farmer John留下深刻印象,他决定推出一个基于新匹配算法的奶牛交友网站,该算法可基于公牛和母牛间的共同兴趣对公牛和母牛进行匹配. Bessie在寻找情人节Barn Dance的合作伙伴时,决定试用这个网站.在注册账户之后,FJ的算法为他给出了一个长度为 N(1≤N≤1e6) 的匹配列表,列表上每头公牛接受她舞蹈邀请的概率为 p (0 < p < 1). Bessie决定向列表中的一个连续区间内的奶牛发送邀请,但Bessie希望恰好只有一

USACO 2017 FEB Gold visitfj 最短路

题意 有一幅n*n的方格图,n <= 100,每个点上有一个值.从(1,1)出发,走到(n,n),只能走四联通.每走一步花费t,每走三步需要花费走完三步后到达格子的值.求最小花费的值. 拆点,dis[i][j]表示到达第i个点时走的总步数模3等于j时的最小花费值. #include <cstdio> #include <cstdlib> #include <cstring> #include <string> #include <algorith