HDU 5669 Road(线段树建树)(分层图最短路)
Posted 贱人方
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 5669 Road(线段树建树)(分层图最短路)相关的知识,希望对你有一定的参考价值。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5669
【分析】线段树建树+分层图最短路
#include <cstdio> #include <map> #include <algorithm> #include <vector> #include <iostream> #include <set> #include <queue> #include <string> #include <cstdlib> #include <cstring> #include <cmath> using namespace std; typedef pair<int,int>pii; typedef long long LL; const int N=6e5+5; const int mod=1e9+7; int n,m,s,k,t,cnt,idl[N<<1],idr[N<<1]; bool vis[N][11]; LL d[N][11]; vector<pii>edg[N]; void buildl(int rt,int l,int r) { idl[rt]=++cnt; if(l==r)return ; int m=l+r>>1; buildl(rt<<1,l,m); buildl(rt<<1|1,m+1,r); edg[idl[rt<<1]].push_back(make_pair(idl[rt],0)); edg[idl[rt<<1|1]].push_back(make_pair(idl[rt],0)); } void buildr(int rt,int l,int r) { idr[rt]=++cnt; if(l==r)return ; int m=l+r>>1; buildr(rt<<1,l,m); buildr(rt<<1|1,m+1,r); edg[idr[rt]].push_back(make_pair(idr[rt<<1],0)); edg[idr[rt]].push_back(make_pair(idr[rt<<1|1],0)); } void pre(int rt,int l,int r) { if(l==r) { edg[l].push_back(make_pair(idl[rt],0)); edg[idr[rt]].push_back(make_pair(l,0)); return; } int m=l+r>>1; pre(rt<<1,l,m); pre(rt<<1|1,m+1,r); } void addl(int rt,int l,int r,int L,int R,int w){ if(L<=l&&r<=R){ edg[idl[rt]].push_back(make_pair(cnt,w)); return; } int mid=(l+r)/2; if(L<=mid)addl(rt*2,l,mid,L,R,w); if(R>mid)addl(rt*2+1,mid+1,r,L,R,w); } void addr(int rt,int l,int r,int L,int R){ if(L<=l&&r<=R){ edg[cnt].push_back(make_pair(idr[rt],0)); return; } int mid=(l+r)/2; if(L<=mid)addr(rt*2,l,mid,L,R); if(R>mid)addr(rt*2+1,mid+1,r,L,R); } struct man{ int v; int c; LL w; bool operator<(const man &e)const{ return w>e.w; } }; priority_queue<man>q; void dij(int s){ memset(d,-1,sizeof d);memset(vis,0,sizeof vis); d[s][0]=0; q.push(man{s,0,0}); while(!q.empty()){ int u=q.top().v,c=q.top().c;q.pop(); if(vis[u][c])continue; vis[u][c]=1; for(int i=0;i<edg[u].size();++i){ int v=edg[u][i].first,w=edg[u][i].second; if(!vis[v][c]&&(d[v][c]==-1||d[v][c]>d[u][c]+w)){ d[v][c]=d[u][c]+w; q.push(man{v,c,d[v][c]}); } if(c<k){ if(!vis[v][c+1]&&(d[v][c+1]==-1||d[v][c+1]>d[u][c])){ d[v][c+1]=d[u][c]; q.push(man{v,c+1,d[v][c+1]}); } } } } } int main() { int x,y,w,l,r; int T; scanf("%d",&T); while(T--){ for(int i=0;i<N;i++)edg[i].clear(); scanf("%d%d%d",&n,&m,&k); cnt=n; buildl(1,1,n); buildr(1,1,n); pre(1,1,n); while(m--) { ++cnt; scanf("%d%d%d%d%d",&x,&y,&l,&r,&w); addl(1,1,n,x,y,w); addr(1,1,n,l,r); cnt++; //此处要注意 addl(1,1,n,l,r,w); addr(1,1,n,x,y); } dij(1); LL ans=1000000000000; for(int i=0;i<=k;i++)ans=min(ans,d[n][i]); if(ans!=-1)printf("%lld\n",ans); else puts("CreationAugust is a sb!"); } return 0; }
以上是关于HDU 5669 Road(线段树建树)(分层图最短路)的主要内容,如果未能解决你的问题,请参考以下文章
2016 Multi-University Training Contest 10 [HDU 5861] Road (线段树:区间覆盖+单点最大小)