当一个点要和一个连续区间内的所有点连权值相同的边时 可以用线段树来优化这个过程 就和区间更新一样的
还有要注意的就是内存对齐问题 node1结构体中的 ll w 如果放在中间的位置就会MLE 具体什么是内存对齐问题就不说了 自行百度
#include <cstdio> #include <queue> #include <cstring> #include <algorithm> using namespace std; #define ll long long #define N 0x3f3f3f3f3f3f3f3f struct node1 { ll w; int v; int next; }; struct node2 { bool friend operator < (node2 n1,node2 n2) { return n1.val>n2.val; } int id; ll val; }; node1 edge[10000010]; priority_queue <node2> que; ll c[200010],dis[1600010]; int l[200010],r[200010],mp[200010],first[1600010],book[1600010]; int n,num,maxx; void addedge(int u,int v,ll w) { edge[num].v=v; edge[num].w=w; edge[num].next=first[u]; first[u]=num++; return; } void build(int l,int r,int cur) { int m; if(l==r) { mp[l]=cur; maxx=max(maxx,mp[l]); return; } addedge(cur,2*cur,0); addedge(cur,2*cur+1,0); m=(l+r)/2; build(l,m,2*cur); build(m+1,r,2*cur+1); return; } void update(int pl,int pr,int tar,int l,int r,int cur) { int m; if(pl<=l&&r<=pr) { addedge(mp[tar],cur,c[tar]); return; } m=(l+r)/2; if(pl<=m) update(pl,pr,tar,l,m,2*cur); if(pr>m) update(pl,pr,tar,m+1,r,2*cur+1); return; } void dijkstra() { node2 cur,tem; ll w; int i,u,v; while(!que.empty()) que.pop(); for(i=0;i<=maxx;i++) { dis[i]=N; book[i]=0; } tem.id=mp[1],tem.val=0; que.push(tem); dis[mp[1]]=0; while(!que.empty()) { cur=que.top(); que.pop(); u=cur.id; if(book[u]) continue; book[u]=1; for(i=first[u];i!=-1;i=edge[i].next) { v=edge[i].v,w=edge[i].w; if(!book[v]&&dis[v]>dis[u]+w) { dis[v]=dis[u]+w; tem.id=v,tem.val=dis[v]; que.push(tem); } } } return; } int main() { int t,i,pl,pr; scanf("%d",&t); while(t--) { scanf("%d",&n); memset(first,-1,sizeof(first)); num=0,maxx=0; for(i=1;i<=n;i++) scanf("%d",&l[i]); for(i=1;i<=n;i++) scanf("%d",&r[i]); for(i=1;i<=n;i++) scanf("%lld",&c[i]); build(1,n,1); for(i=1;i<=n;i++) { pl=i-r[i],pr=i-l[i]; if(pr>=1) { pl=max(1,pl),pr=max(1,pr); update(pl,pr,i,1,n,1); } pl=i+l[i],pr=i+r[i]; if(pl<=n) { pl=min(n,pl),pr=min(n,pr); update(pl,pr,i,1,n,1); } } dijkstra(); for(i=1;i<=n-1;i++) { if(dis[mp[i]]==N) printf("-1 "); else printf("%lld ",dis[mp[i]]); } if(dis[mp[i]]==N) printf("-1\n"); else printf("%lld\n",dis[mp[i]]); } return 0; }