分层最短路

分层图最短路是指在可以进行分层图的图上解决最短路问题。
 
一般模型是:
在图上,有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 }

 我这种方法并不是正规解法(都没分层),但应该可以通过大部分数据,剩下的会超时.........

原文地址:https://www.cnblogs.com/Miroerwf/p/7784172.html