P4083-[USACO17DEC]A Pie for a Pie G【线段树,最短路】
生活随笔
收集整理的這篇文章主要介紹了
P4083-[USACO17DEC]A Pie for a Pie G【线段树,最短路】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
題目鏈接:https://www.luogu.com.cn/problem/P4083
題目大意
開始時AAA和BBB各有兩個禮物,每個禮物對兩個人有不同的價值,開始時AAA會送BBB一個禮物。
對于一個收到禮物的人,如果該禮物對他來說價值為valvalval,那么他會回送一個對于他來說[val,val+d][val,val+d][val,val+d]這個范圍內的禮物。
直到某個人收到價值為000的禮物就停止,求對于AAA開始送的每個禮物,最少要互送多少個禮物才能停止
解題思路
我們可以發現其實就是每次對于一個區間內連邊然后求最短路。
我們對于AAA和BBB各自開一棵線段樹然后優化一下連邊,從價值為000的禮物開始跑,之后直接輸出每個禮物的最短路即可
codecodecode
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<vector> 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\n");else printf("%d\n",f[i]+1);} }總結
以上是生活随笔為你收集整理的P4083-[USACO17DEC]A Pie for a Pie G【线段树,最短路】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CF590E-Birthday【AC自动
- 下一篇: 科兴第二针21天还是28天