P4083 - [USACO17DEC] A Pie for a Pie G [선분 수, 최 단 길]
제목 링크:https://www.luogu.com.cn/problem/P4083
제목 의 대의
처음에 A A 와 B B B 는 각각 두 개의 선물 이 있 었 고 선물 마다 두 사람 에 게 서로 다른 가치 가 있 었 다. 처음에 A A 는 B B B 에 게 선물 을 주 었 다.선물 을 받 은 사람 에 게 이 선물 이 그 에 게 v a l val 의 가치 가 있다 면 그 는 그 에 게 [v a l, v a l + d] [val, val + d] [val, val + d] 라 는 범위 안의 선물 을 돌려 줄 것 이다.누 군가 에 게 서 000 원 짜 리 선물 을 받 을 때 까지 멈 추고, A A A 가 주기 시작 한 모든 선물 에 대해 최소한 몇 개의 선물 을 주 고 받 아야 멈 출 수 있 는 지
문제 풀이 의 사고 방향.
우 리 는 사실 매번 한 구간 의 내 연 변 에 대해 최 단 로 를 구 하 는 것 을 발견 할 수 있다.
우 리 는 A A A 와 B B B 에 대해 각각 선분 나 무 를 한 그루 씩 열 고 연결 을 최적화 시 켜 0, 0 의 가치 가 있 는 선물 부터 달 린 다음 에 모든 선물의 최 단 길 을 직접 출력 하면 된다.
c o d e code code
#include
#include
#include
#include
#include
using namespace std;
const int N=1e5*20;
struct node{
int to,next,w;
}a[N*2];
struct gnode{
int x,y,w,id;
}g[N],b[N];
int n,d,num,tot,cnt,rt0,rt1;
int ls[N],in[N],f[N],w[N];
int lson[N],rson[N],v1[N],v2[N];
bool vis[N];
queue<int> q;
void addl(int x,int y,int w){
a[++tot].to=x;
a[tot].next=ls[y];
a[tot].w=w;ls[y]=tot;
}
void Build(int &x,int l,int r,int z){
x=++num;
if(l==r){
if(z)addl(x,g[l].id,0);
else addl(x,b[l].id,0);
return;
}
int mid=(l+r)>>1;
Build(lson[x],l,mid,z);
Build(rson[x],mid+1,r,z);
addl(x,lson[x],0);addl(x,rson[x],0);
return;
}
void Change(int x,int L,int R,int l,int r,int pos){
if(l>r)return;
if(L==l&&R==r)
{addl(pos,x,1);return;}
int mid=(L+R)>>1;
if(r<=mid)Change(lson[x],L,mid,l,r,pos);
else if(l>mid)Change(rson[x],mid+1,R,l,r,pos);
else Change(lson[x],L,mid,l,mid,pos),Change(rson[x],mid+1,R,mid+1,r,pos);
return;
}
void SPFA(){
while(!q.empty()){
int x=q.front();q.pop();
for(int i=ls[x];i;i=a[i].next){
int y=a[i].to;
if(f[x]+a[i].w<f[y]){
f[y]=f[x]+a[i].w;
if(!vis[y]){
q.push(y);
vis[y]=1;
}
}
}
vis[x]=0;
}
}
bool cmp1(gnode x,gnode y)
{return x.x<y.x;}
bool cmp2(gnode x,gnode y)
{return x.y<y.y;}
int main()
{
scanf("%d%d",&n,&d);
for(int i=1;i<=n;i++)
scanf("%d%d",&b[i].x,&b[i].y),b[i].id=i;
for(int i=1;i<=n;i++)
scanf("%d%d",&g[i].x,&g[i].y),g[i].id=i+n;
sort(b+1,b+1+n,cmp1);
sort(g+1,g+1+n,cmp2);
num=n*2;
Build(rt0,1,n,0);
Build(rt1,1,n,1);
for(int i=1;i<=n;i++)v1[i]=b[i].x;
for(int i=1;i<=n;i++)v2[i]=g[i].y;
sort(b+1,b+1+n,cmp2);
sort(g+1,g+1+n,cmp1);
int link=1;
memset(f,0x3f,sizeof(f));
for(int i=1;i<=n;i++){
int l=lower_bound(v2+1,v2+1+n,b[i].y)-v2;
int r=upper_bound(v2+1,v2+1+n,b[i].y+d)-v2-1;
Change(rt1,1,n,l,r,b[i].id);
if(!b[i].y)q.push(b[i].id),f[b[i].id]=0,vis[b[i].id]=1;
}
for(int i=1;i<=n;i++){
int l=lower_bound(v1+1,v1+1+n,g[i].x)-v1;
int r=upper_bound(v1+1,v1+1+n,g[i].x+d)-v1-1;
Change(rt0,1,n,l,r,g[i].id);
if(!g[i].x)q.push(g[i].id),f[g[i].id]=0,vis[g[i].id]=1;
}
SPFA();
for(int i=1;i<=n;i++){
if(f[i]>2147483647/3)printf("-1
");
else printf("%d
",f[i]+1);
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
HDU 1874: 원활 한 공사 계속 [Dijkstra & SPFA & Floyd]모 성 은 여러 해 동안 의 원활 한 공사 계획 을 실행 한 후에 마침내 많은 길 을 건설 하 였 다.길 을 많이 건 너 지 않 아 도 좋 지 않다. 한 도시 에서 다른 도시 로 갈 때마다 여러 가지 도로 방안 을 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.