BestCoder Round #80 E Road (hdu5669) 【线段树+分层图最短路】
来源:互联网 发布:fedora yum 源 编辑:程序博客网 时间:2024/06/05 01:59
链接:http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=688&pid=1005
题意:中文题
分析:官方题解说的很详细了这里就不转了,关键部分已经注释了
代码:
#include <algorithm>#include <iostream>#include <iostream>#include <cstring>#include <cstdio>#include <string>#include <vector>#include <queue>#include <cmath>#include <stack>#include <set>#include <map>#include <ctime>#define INF 0x7fffffff#define Mn 50010*10#define Mm 2000010#define mod 1000000007#define CLR(a,b) memset((a),(b),sizeof((a)))#define CPY(a,b) memcpy ((a), (b), sizeof((a)))#pragma comment(linker, "/STACK:102400000,102400000")#define ul (u<<1)#define ur ((u<<1)|1)#define cnt 4*nusing namespace std;typedef long long ll;struct edge { int v,w,next;}e[Mm];struct node { int v,cost; node(){} node(int v,int cost):v(v),cost(cost){} bool operator <(const node a) const { return a.cost<cost; }};int tot,head[Mn];void addedge(int u,int v,int w) { e[tot].v=v; e[tot].w=w; e[tot].next=head[u]; head[u]=tot++;}int tr[Mn],tr2[Mn];int n,k;void build(int l,int r,int u) { if(l==r) { tr[l]=u; tr2[l]=cnt+u;//第二棵线段树 addedge(tr2[l],tr[l],0);//回到第一颗线段树上 return ; } int mid=(l+r)>>1; build(l,mid,ul); build(mid+1,r,ur); addedge(ul,u,0);//第一棵线段树中 儿子连向父亲 表示 如果父亲有连向第二棵线段树的边 a b addedge(ur,u,0);//则该点可以通过父亲的边连向第二课线段树c d addedge(cnt+u,cnt+ul,0);//第二棵线段树中 父亲连向儿子 表示上面节点可以通过该边找到实际的节点 c d addedge(cnt+u,cnt+ur,0);}int s,t,w,tmp;//tmp为两线段树相连的中间结点void query(int l,int r,int u) { if(s<=l&&t>=r) { addedge(u,tmp,0); return ; } int mid=(l+r)>>1; if(s<=mid) query(l,mid,ul); if(t>mid) query(mid+1,r,ur);}void query2(int l,int r,int u) { if(s<=l&&t>=r) { addedge(tmp,u+cnt,w); return ; } int mid=(l+r)>>1; if(s<=mid) query2(l,mid,ul); if(t>mid) query2(mid+1,r,ur);}priority_queue<node> q;int dis[Mn][11],vis[Mn][11];int ans;void dijkstra(int st,int ed) { st=tr[st];ed=tr2[ed]; while(!q.empty()) q.pop(); q.push(node(st,0)); CLR(dis,0x7f); CLR(vis,0); dis[st][0]=0; while(!q.empty()) { int v=q.top().v; int u=(v-1)%tmp+1;//求出节点和所在层数 这里是为了在优先队列里少存一个数 int x=(v-u)/tmp; q.pop(); if(vis[u][x]) continue; vis[u][x]=1; for(int i=head[u];~i;i=e[i].next) { int v=e[i].v; int cost=e[i].w; if(!vis[v][x]&&dis[v][x]>dis[u][x]+cost) { dis[v][x]=dis[u][x]+cost; q.push(node(v+x*tmp,dis[v][x])); } if(x<k) { if(!vis[v][x+1]&&dis[v][x+1]>dis[u][x]) { dis[v][x+1]=dis[u][x]; q.push(node(v+(x+1)*tmp,dis[v][x+1])); } } } } for(int i=0;i<=k;i++) ans=min(ans,dis[ed][i]);}void init() { tot=0; CLR(head,-1);}int main() { init(); int m,a,b,c,d; scanf("%d",&n); scanf("%d%d%d",&n,&m,&k); build(1,n,1); tmp=cnt*2; for(int i=0;i<m;i++) { scanf("%d%d%d%d%d",&a,&b,&c,&d,&w); tmp++;s=a;t=b; query(1,n,1); s=c;t=d; query2(1,n,1); tmp++; query(1,n,1); //边是双向的 s=a;t=b; query2(1,n,1); } ans=INF; dijkstra(1,n); if(ans>=INF) printf("CreationAugust is a sb!\n"); else printf("%d\n",ans); return 0;}
0 0
- BestCoder Round #80 E Road (hdu5669) 【线段树+分层图最短路】
- bzoj4992 [Usaco2017 Feb]Why Did the Cow Cross the Road(分层图最短路)
- HDU5669 Road
- Aizu1311 分层图最短路 (...大概)
- BZOJ3040最短路(road)
- hdu3499(分层图最短路)
- 分层图最短路 bzoj2763
- BestCoder Round #50 digger(动态生成线段树)
- HDU 5751 BestCoder Round #84 Eades(线段树+FFT)
- BZOJ2750 [HAOI2012]Road(最短路)
- 3040: 最短路(road)
- 3040: 最短路(road)
- 【bzoj3040】最短路(road)
- bzoj3040: 最短路(road)
- 【bzoj3040】最短路(road)
- HDU 3499 分层图最短路+Trie树
- 汽车加油行驶问题(分层图最短路)
- BZOJ2763 [JLOI2011]飞行路线(分层图最短路)
- i+++j
- 【补丁】在vs2015、vs emulator for android下挪动android sdk文件夹
- 常见HTTP状态码(200、301、302、500等)解说
- eclipse发布web项目时提示无法找到外部包的类
- HDU 3367 Pseudoforest(Kruskal)
- BestCoder Round #80 E Road (hdu5669) 【线段树+分层图最短路】
- 进程死锁条件和银行家算法
- 构建之法3
- Java中子类继承了父类的私有属性及方法吗?
- 2-1 Verilog 3-8 译码器
- poj 3070 java实现矩阵快速幂
- hibernate mysql查询首字母排序两表连接外键
- Bestcoder Pro.ID 2012 素数判定
- LeetCode 70. Climbing Stairs