分析:
又是区间连边,所以考虑用线段树优化建图
设
dis[i][j]
d
i
s
[
i
]
[
j
]
表示到点
i
i
,飞行了次的最小距离
dijkstra转移即可
tip
%%%CA爷
看了一下前辈的题解,发现有一种叫做“分层图最短路”的算法
好高大上,实际上就是
dis[i][j]
d
i
s
[
i
]
[
j
]
的转移(这不是dp吗)。。。orz
WA了。。。拍不出什么错误啊
没招了,想看AC代码的同学们请移步其他blog吧
下面的代码可以用来对拍,但是不能AC(一点用都没有好伐)
求dalao指点
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
const int N=500010;
const int M=5000010;
struct node{
int y,nxt,v;
};
node way[M];
int n,m,K,st[N],tot,cnt,pos[N],INF;
int dis[50005][12];
void add(int u,int w,int z) {
tot++;way[tot].y=w;way[tot].v=z;way[tot].nxt=st[u];st[u]=tot;
}
void build(int bh,int l,int r) {
if (l==r) {
pos[l]=bh;
add(bh+4*n,bh,0); //入树->出树
return;
}
int mid=(l+r)>>1;
build(bh<<1,l,mid);
build(bh<<1|1,mid+1,r);
int lc=bh<<1,rc=bh<<1|1;
add(lc,bh,0); add(rc,bh,0);
add(bh+4*n,lc+4*n,0);
add(bh+4*n,rc+4*n,0);
}
void change(int bh,int l,int r,int L,int R,int w,int opt,int z) {
if (l>=L&&r<=R) {
if (!opt) add(bh,w,0);
else add(w,bh+4*n,z);
return;
}
int mid=(l+r)>>1;
if (L<=mid) change(bh<<1,l,mid,L,R,w,opt,z);
if (R>mid) change(bh<<1|1,mid+1,r,L,R,w,opt,z);
}
struct point{
int u,k,dis;
point(int uu=0,int kk=0,int d=0) {
u=uu;k=kk;dis=d;
}
bool operator <(const point &b) const {
return dis>b.dis;
}
};
priority_queue<point> q;
bool vis[50005][12];
void dijkstra() {
memset(dis,0x7f,sizeof(dis));
INF=dis[0][0]; dis[pos[1]][0]=0;
memset(vis,0,sizeof(vis));
q.push(point(pos[1],0,0));
while (!q.empty()) {
point now=q.top(); q.pop();
if (vis[now.u][now.k]) continue;
vis[now.u][now.k]=1;
int u=now.u,k=now.k;
for (int i=st[u];i;i=way[i].nxt) {
int y=way[i].y;
if (dis[y][k]>dis[u][k]+way[i].v) {
dis[y][k]=dis[u][k]+way[i].v;
q.push(point(y,k,dis[y][k]));
}
if (k+1<=K&&dis[y][k+1]>dis[u][k]) {
dis[y][k+1]=dis[u][k];
q.push(point(y,k+1,dis[y][k+1]));
}
}
}
int ans=INF;
for (int i=0;i<=K;i++) ans=min(ans,dis[pos[n]][i]);
if (ans!=INF) printf("%d\n",ans);
else printf("CreationAugust is a sb!\n");
}
int main()
{
int T;
scanf("%d",&T);
while (T--) {
memset(st,0,sizeof(st));
tot=0;
scanf("%d%d%d",&n,&m,&K);
int a,b,c,d,z;
build(1,1,n);
cnt=n<<3;
for (int i=1;i<=m;i++) {
scanf("%d%d%d%d%d",&a,&b,&c,&d,&z);
change(1,1,n,a,b,++cnt,0,0); change(1,1,n,c,d,cnt,1,z);
change(1,1,n,c,d,++cnt,0,0); change(1,1,n,a,b,cnt,1,z);
}
dijkstra();
}
return 0;
}