把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

Luogu P4568 【[JLOI2011]飞行路线】题解

分层图的模版题
什么是分层图
分层图--------可以理解为有多个平行的图
第i层表示用了i张免费卷后到达每个点的最短路
显然,可以在同层跑最短路,而低层可以到高层
这就满足了在不同层间无后效性的拓展
于是我们可以设状态

dis[i][j]//表示在第j层(用j张免费卷)到第i个点的最短路径
dis[i][j]=Min(Min{dis[k][j]+value[k][i]},Min{dis[k][j-1]})
//k为与i联通的点

献上我丑陋的代码:

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define ll long long

struct point{
    ll d,id,dep;
    bool operator <(const point &a)const{
        return d>a.d;
    }
};

priority_queue<point>q;

ll u[100005],v[100005],w[100005];
ll first[10005],next[100005];
ll tot=0;

inline void addedge(ll a,ll b,ll c){
    tot++;u[tot]=a,v[tot]=b,w[tot]=c;
    next[tot]=first[a];first[a]=tot;
}

ll dis[10005][15];
ll vis[10005][15];
ll n,m,k;

//管它卡不卡spfa,dij+heap常规操作
ll dijkstra(ll s,ll t){
    memset(dis,0x3f,sizeof dis);
    dis[s][0]=0;q.push({0,s,0});vis[s][0]=1;
    while(!q.empty()){
        point p=q.top();q.pop();
        ll x=p.id,op=p.dep,d=p.d;
        
        if(d!=dis[x][op])continue;
        vis[x][op]=1;
        
        for(int i=first[x];i;i=next[i]){
            int y=v[i];
            if(!vis[y][op]){
				if(dis[y][op]>dis[x][op]+w[i]){
					dis[y][op]=dis[x][op]+w[i];
					q.push({dis[y][op],y,op});
				}
            }
            if(op<k&&!vis[y][op+1]){
            	if(dis[y][op+1]>dis[x][op]){
            		dis[y][op+1]=dis[x][op];
            		q.push({dis[y][op+1],y,op+1});
				}
			}
        }
    }
    return dis[t][k];
}

int main(){
    scanf("%lld%lld%lld",&n,&m,&k);
    ll s,t;scanf("%lld%lld",&s,&t);
    for(ll i=1;i<=m;i++){
        ll a,b,c;scanf("%lld%lld%lld",&a,&b,&c);
        addedge(a,b,c);addedge(b,a,c);
    }
    printf("%lld",dijkstra(s,t));
    return 0;
}
posted @ 2018-11-15 20:14  蒟蒻的吸取教训  阅读(179)  评论(0编辑  收藏  举报
Live2D
他们一旦抱有某种成见,那一切查证就得符合这一成见,如果某…