bzoj2763: [JLOI2011]飞行路线 分层图+dij+heap
分析:d[i][j]代表从起点到点j,用了i次免费机会,那就可以最短路求解
#include <stdio.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <string.h> using namespace std; typedef long long LL; const int INF=0x3f3f3f3f; const int N=1e4+5; int d[12][N],head[N],tot,n,m,k,s,t; struct Edge{ int v,w,next; }edge[10*N]; void add(int u,int v,int w){ edge[tot].v=v; edge[tot].w=w; edge[tot].next=head[u]; head[u]=tot++; } struct Node{ int cur,v,dis; bool operator<(const Node &rhs)const{ return dis>rhs.dis; } }; priority_queue<Node>q; bool vis[12][N]; int dij(){ memset(d,INF,sizeof(d)); memset(vis,0,sizeof(vis)); d[0][s]=0; q.push(Node{0,s,0}); while(!q.empty()){ int cur=q.top().cur,u=q.top().v; q.pop(); if(vis[cur][u])continue; vis[cur][u]=1; for(int i=head[u];~i;i=edge[i].next){ int v=edge[i].v; if(!vis[cur][v]&&d[cur][v]>d[cur][u]+edge[i].w){ d[cur][v]=d[cur][u]+edge[i].w; q.push(Node{cur,v,d[cur][v]}); } if(cur+1>k)continue; if(!vis[cur+1][v]&&d[cur+1][v]>d[cur][u]){ d[cur+1][v]=d[cur][u]; q.push(Node{cur+1,v,d[cur+1][v]}); } } } return d[k][t]; } int main(){ scanf("%d%d%d",&n,&m,&k); memset(head,-1,sizeof(head)),tot=0; scanf("%d%d",&s,&t); for(int i=1;i<=m;++i){ int u,v,w; scanf("%d%d%d",&u,&v,&w); add(u,v,w),add(v,u,w); } printf("%d\n",dij()); return 0; }