Description
Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司。该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定的价格。Alice和Bob现在要从一个城市沿着航线到达另一个城市,途中可以进行转机。航空公司对他们这次旅行也推出优惠,他们可以免费在最多k种航线上搭乘飞机。那么Alice和Bob这次出行最少花费多少?
Input
数据的第一行有三个整数,n,m,k,分别表示城市数,航线数和免费乘坐次数。
第二行有两个整数,s,t,分别表示他们出行的起点城市编号和终点城市编号。(0<=s,t
接下来有m行,每行三个整数,a,b,c,表示存在一种航线,能从城市a到达城市b,或从城市b到达城市a,价格为c。(0<=a,b
Output
只有一行,包含一个整数,为最少花费。
Sample Input 1
5 6 1
0 4
0 1 5
1 2 5
2 3 5
3 4 5
2 3 3
0 2 100
Sample Output 1
8
Hint
对于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
题目模型:一般的最短路,但是有k次机会使得某条权值为0,或者减半。求最短路径。
dis[i][j] 表示 第i点使用j次权力
v:下个点 u:父节点,
dis[v][k] = dis[u][k] + cost[u][v] ---->不使用权力
dis[v][k+1]=dis[u][k] ----->使用权力
然后遍历 dis[ed][0_k] ,求最小值,因为可能dis[ed][k]不是最小(路径长度小于k)
真正的分层图
见博客:https://blog.csdn.net/sugarbliss/article/details/86551050
不同的建图,点数和边数不一样,注意数组大小。
1 #include
2 using namespace std;
3 const int inf=0x3f3f3f3f;
4 const int maxn=10010;
5 const int maxm=100010;
6
7 int n,m,k,st,ed;
8 int head[maxn],dis[maxn][15];
9 bool vis[maxn][15];
10
11 struct Edge{
12 int to,next,w;
13 }edge[maxm];
14
15 int tol;
16 void addedge(int u,int v,int w) {
17 edge[tol].to=v;
18 edge[tol].w=w;
19 edge[tol].next=head[u];
20 head[u]=tol++;
21 }
22
23 void init() {
24 tol=0;
25 for(int i=0;i<=n;i++) {
26 head[i]=-1;
27 for(int j=0;j<=15;j++) {
28 dis[i][j]=inf;
29 vis[i][j]=false;
30 }
31 }
32 }
33
34 struct node{
35 int u,step;
36 node(){}
37 node(int _u,int _step) {
38 u=_u;
39 step=_step;
40 }
41 };
42
43 void spfa() {
44 dis[st][0]=0;
45 queue q;
46 vis[st][0]=true;
47 q.push(node(st,0));
48 while(!q.empty()) {
49 node f=q.front();
50 q.pop();
51 vis[f.u][f.step]=false;
52 for(int i=head[f.u];i!=-1;i=edge[i].next) {
53 int v=edge[i].to;
54 if(dis[v][f.step]>dis[f.u][f.step]+edge[i].w) {
55 dis[v][f.step]=dis[f.u][f.step]+edge[i].w;
56 if(!vis[v][f.step]) {
57 vis[v][f.step]=true;
58 q.push(node(v,f.step));
59 }
60 }
61 if(f.step+1<=k) {
62 if(dis[v][f.step+1]>dis[f.u][f.step]) {
63 dis[v][f.step+1]=dis[f.u][f.step];
64 if(!vis[v][f.step+1]) {
65 vis[v][f.step+1]=true;
66 q.push(node(v,f.step+1));
67 }
68 }
69 }
70 }
71 }
72 }
73
74 int main() {
75 while(~scanf("%d%d%d",&n,&m,&k)) {
76 init();
77 scanf("%d%d",&st,&ed);
78 for(int i=1;i<=m;i++) {
79 int u,v,w;
80 scanf("%d%d%d",&u,&v,&w);
81 addedge(u,v,w);
82 addedge(v,u,w);
83 }
84 spfa();
85 int ans=inf;
86 for(int i=0;i<=k;i++) ans=min(ans,dis[ed][i]);
87 printf("%d\n",ans);
88 }
89 }