提交传送门
师兄们觉得我是不是很挫啊,做了1天多才做出这道裸Spfa…
人家只是试着打了一下拆点而已嘛……
就是Spfa只是2维而已
d[i][0]代表第i个点 不用免费次数时得最小距离
d[i][1]代表第i个点 用免费次数时得最小距离
就很简单了是不是?
Description
Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司。该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定的价格。Alice和Bob现在要从一个城市沿着航线到达另一个城市,途中可以进行转机。航空公司对他们这次旅行也推出优惠,他们可以免费在最多k种航线上搭乘飞机。那么Alice和Bob这次出行最少花费多少?
Input
数据的第一行有三个整数,n,m,k,分别表示城市数,航线数和免费乘坐次数。第二行有两个整数,s,t,分别表示他们出行的起点城市编号和终点城市编号。(0<=s,t
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
struct node{
int x,y,c,next;
}a[210000];int len,first[110000];
void ins(int x,int y,int c){
len++;
a[len].x=x;a[len].y=y;a[len].c=c;
a[len].next=first[x];first[x]=len;
}
int d[110000][11],list[110000][11],head,tail,ans,n,m,p,st,ed;;
bool v[110000][11];
int main(){
scanf("%d%d%d",&n,&m,&p);
scanf("%d%d",&st,&ed);
for(int i=1;i<=m;i++){
int x,y,c;
scanf("%d%d%d",&x,&y,&c);
ins(x,y,c);ins(y,x,c);
}
memset(d,31,sizeof(d));d[st][0]=0;
memset(v,false,sizeof(v));v[st][0]=true;
head=1;tail=2;list[1][0]=st;list[1][1]=0;
while(head!=tail){
int x=list[head][0];int c=list[head][1];
for(int k=first[x];k>0;k=a[k].next){
int y=a[k].y;
if(d[x][c]+a[k].c<d[y][c]){
d[y][c]=d[x][c]+a[k].c;
if(v[y][c]==false){
v[y][c]=true;
list[tail][0]=y;list[tail++][1]=c;
if(tail==100001) tail=1;
}
}
if(d[x][c]<d[y][c+1]&&c<p){
d[y][c+1]=d[x][c];
if(v[y][c+1]==false){
v[y][c+1]=true;
list[tail][0]=y;list[tail++][1]=c+1;
if(tail==100001) tail=1;
}
}
}
head++;
if(head==100001) head=1;
v[x][c]=false;
}
ans=999999999;
for(int i=0;i<=p;i++)ans=min(ans,d[ed][i]);
printf("%d\n",ans);
return 0;
}