分层图最短路是指在可以进行分层图的图上解决最短路问题。
一般模型是:
在图上,有k次机会可以直接通过一条边,问起点与终点之间的最短路径。
我们拥有k次机会可以免费通过,所以我们可以设dis【i】【j】表示在还剩j次免花费机会的情况下到i的最小花费,然后在图上进行一次SPFA,对dis【T】【i】取min即可。
1 #include<iostream> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cstdio> 5 #include<cmath> 6 #include<queue> 7 #include<algorithm> 8 using namespace std; 9 const int N=10010; 10 const int M=50010; 11 inline int read(){ 12 int x=0,f=1; char ch=getchar(); 13 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 14 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 15 return x*f; 16 } 17 void print(int x){ 18 if(x<0) 19 putchar('-'),x=-x; 20 if (x>9) 21 print(x/10); 22 putchar(x%10+'0'); 23 } 24 int vis[N],head[M*2],num,dis[N][21],n,m,k,ans; 25 struct node 26 { 27 int next; 28 int to; 29 int w; 30 } t[M*2]; 31 void add(int x,int y,int z){ 32 t[++num].next=head[ x ]; 33 t[num].to=y; 34 t[num].w=z; 35 head[x]=num; 36 } 37 void spfa(){ 38 queue<int>q; 39 q.push(1); vis[1]=1; 40 while(!q.empty()) 41 { 42 int x=q.front(); q.pop(); 43 vis[x]=0; 44 for(int i=head[x];i;i=t[i].next) 45 { 46 int y=t[i].to; 47 if(dis[x][k]+t[i].w<dis[y][k]){/*走这条路*/ 48 dis[y][k]=dis[x][k]+t[i].w; 49 if(!vis[y]) 50 vis[y]=1,q.push(y); 51 } 52 for(int j=k-1;j>=0;j--) 53 if( dis[x][j]+t[i].w<dis[y][j]||dis[x][j+1]<dis[y][j]){/*这条路走或者升级*/ 54 dis[y][j]=min(min(dis[x][j]+t[i].w,dis[x][j+1]),dis[y][j]); 55 if(!vis[y]) 56 vis[y]=1,q.push(y); 57 } 58 } 59 } 60 } 61 int main() 62 { 63 memset(dis,0x7f,sizeof dis); 64 n=read(); m=read(); k=read(); 65 for(int i=0;i<=k;i++) 66 dis[1][i]=0; 67 for(int i=1;i<=m;i++){ 68 int x,y,z; scanf("%d%d%d",&x,&y,&z); 69 add(x,y,z),add(y,x,z); 70 } 71 spfa(); ans=0x7fffffff; 72 for(int i=0;i<=k;i++) 73 ans=min( ans,dis[n][i]); 74 print(ans); 75 return 0; 76 }
我这种方法并不是正规解法(都没分层),但应该可以通过大部分数据,剩下的会超时.........