标签:line 完成 ESS strong 优化 continue 模型 text for
首先注意到题目中的几个性质:
那么基于此,设 \(B_i\) 为Bessie做的第 \(i\) 个 \(\pi\) 的答案、 \(E_i\) 为Elsie做的第 \(i\) 个 \(\pi\) 的答案,我们可以设出转移方程:
\(f_i=\begin{cases}1&\text{如果Elsie的评价为0}\\\min{\{E_j\}}&\text{如果Elsie对当前}\pi\text{的评价}\leq\text{对Elsie做的第}j\text{个}\pi\text{的评价}\end{cases}\)
\(E_i=\begin{cases}1&\text{如果Bessie的评价为0}\\\min{\{F_j\}}&\text{如果Bessie对当前}\pi\text{的评价}\leq\text{对Bessie做的第}j\text{个}\pi\text{的评价}\end{cases}\)
明显的(也就想了我半个小时),这是一个最短路的模型,所以我们把Bessie做的 \(\pi\) 设成 \(1\)~\(n\) 号点,把Elsie做的 \(\pi\) 设成 \(n+1\)~\(n+n\) 号点,然后建图,然后跑最短路即可。
建图明显是 \(n^2\) 的(其实本来就是 \(n^2\) 的,但是数据……),考虑优化至\(n\log{n}\),有两种方法:
把Bessie做的 \(\pi\) 按Bessie的评价排序,把Elsie做的 \(\pi\) 按Elsie的评价排序。
对于一个Bessie做的 \(\pi\) ,用二分找到最小可以让Elsie送出哪个 \(\pi\) ,然后一个一个建边直到不能建边为止。对于Elsie做的 \(\pi\) 同理。
把所有的 \(\pi\) copy一份放在另一个数组里,然后Bessie的 \(\pi\) 分别按Bessie的评价和Elsie的评价排序。对于Elsie做的 \(\pi\) 同理。
对于一个Bessie做的 \(\pi\) ,用另一个只增不减的指针找到最小可以让Elsie送出哪个 \(\pi\) ,然后再用一个循环一个一个建边直到不能建边为止。对于Elsie做的 \(\pi\) 同理。
注意:连边时要反着连,然后再构造一个源点连到每一个“出口”的点(即 \(F_i\) 或 \(E_i\) 为1的点)。并不需要特殊处理答案,对于一个点只要有一个0就可以认为是“出口”(数据过水)。
然后建图就完成了,跑最短路即可。
Warning:建边部分可能引起不适,请谨慎观看
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,w[200010],a[200010][2],cb[2][100010],ce[2][100010],last,h[200010],b[1500010][2],d[200010];
bool bz[200010];
void read(int &x){
char c=getchar();
for(;c<33;c=getchar());
for(x=0;(47<c)&&(c<58);x=x*10+c-48,c=getchar());
}
bool comp1(int x,int y){
return(a[x][0]<a[y][0]);
}
bool comp2(int x,int y){
return(a[x][1]<a[y][1]);
}
void add(int x,int y){
b[++last][0]=h[x];
b[last][1]=y;
h[x]=last;
}
void spfa(){
int dh=0,dt=1;
memset(w,127,sizeof(w));
w[0]=0;
while(dh<dt){
for(int i=h[d[++dh]];i;i=b[i][0]){
if(w[b[i][1]]>w[d[dh]]+1){
w[b[i][1]]=w[d[dh]]+1;
if(!bz[b[i][1]]){
d[++dt]=b[i][1];
bz[b[i][1]]=1;
}
}
}
bz[d[dh]]=0;
}
}
int main(){
freopen("piepie.in","r",stdin);
freopen("piepie.out","w",stdout);
read(n);read(m);
for(int i=1;i<=n;i++){
read(a[i][0]);read(a[i][1]);
cb[0][i]=cb[1][i]=i;
}
for(int i=1;i<=n;i++){
read(a[i+n][0]);read(a[i+n][1]);
ce[0][i]=ce[1][i]=i+n;
}
sort(cb[0]+1,cb[0]+n+1,comp1);
sort(cb[1]+1,cb[1]+n+1,comp2);
sort(ce[0]+1,ce[0]+n+1,comp1);
sort(ce[1]+1,ce[1]+n+1,comp2);
for(int i=1,j=1;i<=n;i++){
for(;a[cb[1][i]][1]>a[ce[1][j]][1]&&j<=n;j++);
if(a[cb[1][i]][1]==0){
add(0,cb[1][i]);
continue;
}
for(int k=j;a[cb[1][i]][1]+m>=a[ce[1][k]][1]&&k<=n;add(ce[1][k],cb[1][i]),k++);
}
for(int i=1,j=1;i<=n;i++){
for(;a[ce[0][i]][0]>a[cb[0][j]][0]&&j<=n;j++);
if(a[ce[0][i]][0]==0){
add(0,ce[0][i]);
continue;
}
for(int k=j;a[ce[0][i]][0]+m>=a[cb[0][k]][0]&&k<=n;add(cb[0][k],ce[0][i]),k++);
}
spfa();
for(int i=1;i<=n;i++){
printf("%d\n",w[i]==0x7f7f7f7f?-1:w[i]);
}
fclose(stdin);
fclose(stdout);
return(0);
}
【USACO 2017 December Gold】A Pie for a Pie 题解
标签:line 完成 ESS strong 优化 continue 模型 text for
原文地址:https://www.cnblogs.com/groundwater/p/13027194.html