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;
}
View Code

 

posted @ 2016-04-20 21:23  shuguangzw  阅读(177)  评论(0编辑  收藏  举报