[JLOI2011]飞行路线题解

    科技2024-09-28  17

    题目描述

    Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司。该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定的价格。Alice和Bob现在要从一个城市沿着航线到达另一个城市,途中可以进行转机。航空公司对他们这次旅行也推出优惠,他们可以免费在最多k种航线上搭乘飞机。那么Alice和Bob这次出行最少花费多少?

    输入格式

    数据的第一行有三个整数,n,m,k,分别表示城市数,航线数和免费乘坐次数。

    第二行有两个整数,s,t,分别表示他们出行的起点城市编号和终点城市编号。(0<=s,t<n)

    接下来有m行,每行三个整数,a,b,c,表示存在一种航线,能从城市a到达城市b,或从城市b到达城市a,价格为c。(0<=a,b<n,a与b不相等,0<=c<=1000)

    输出格式

    只有一行,包含一个整数,为最少花费。

    样例

    样例输入

    5 6 1 0 4 0 1 5 1 2 5 2 3 5 3 4 5 2 3 3 0 2 100

    样例输出

    8

    数据范围与提示

    对于30%的数据,2<=n<=50,1<=m<=300,k=0;

    对于50%的数据,2<=n<=600,1<=m<=6000,0<=k<=1;

    对于100%的数据,2<=n<=10000,1<=m<=50000,0<=k<=10.

    题解

    乍一看,哇塞,这不是分层图最短路的板子吗???

    又一看,哇塞,不会打分层图

    于是采取其它的方法;

    仔细一看,可以DP呀!!!

    对于定义dp[i][j],表示第i点到源点使用了j次免费机会的最短路径;

    那么到达dp[i][j]的方式有两种

    由i所连接的点直接到达i;由i所连接的点使用一次免费后到达i;

    所以dp[i][j]=min(dp[v][j-1],dp[v][j]+w)

    其中,v为所有连接i的店,w为其边权;

    代码

    #include<bits/stdc++.h> using namespace std; struct zz{ int u,w,k; }; bool operator <(zz a,zz b){ return a.w>b.w; } vector<zz> v[10005]; int dp[10005][15]; bool f[10005][15]; int n,m,tot; void Dijkstra(int st,int ed){ memset(dp,0x3f,sizeof dp); dp[st][0]=0; priority_queue<zz> q; q.push(zz{st,0,0}); while(q.size()){ zz now; now=q.top(); int nowk=now.k; int nowans=now.w; int u=now.u; q.pop(); if(f[u][nowk]) continue; f[u][nowk]=1; for(int i=0;i<v[u].size();i++){ int u1=v[u][i].u; int w=v[u][i].w; if(dp[u1][nowk]>dp[u][nowk]+w&&!f[u1][nowk]){ dp[u1][nowk]=dp[u][nowk]+w; q.push(zz{u1,dp[u1][nowk],nowk}); } if(nowk+1<=tot){ if(dp[u1][nowk+1]>dp[u][nowk]&&!f[u1][nowk+1]){ dp[u1][nowk+1]=dp[u][nowk]; q.push(zz{u1,dp[u1][nowk+1],nowk+1}); } } } } int Min=0x3f3f3f3f; for(int i=0;i<=tot;i++){ Min=min(Min,dp[ed][i]); //printf("%d %d %d\n",ed,i,dp[ed][i]); } printf("%d",Min); } int main(){ int st,ed; scanf("%d%d%d",&n,&m,&tot); scanf("%d%d",&st,&ed); for(int i=1;i<=m;i++){ int x,y,z; scanf("%d%d%d",&x,&y,&z); v[x].push_back(zz{y,z,0}); v[y].push_back(zz{x,z,0}); } Dijkstra(st,ed); return 0; }
    Processed: 0.009, SQL: 8