HRBUST1404 Leyni的汽车比赛 题解报告

题目传送门

【题目大意】

【思路分析】

看到问题要求“最少”,于是理所当然地想到DP啦。

设$f[i][j][k]$表示从$i$城到$j$城,途中换了$k$次车所需的最小时间,然后可以想到转移方程:

$$f[i][j][k]=min(f[i][j][k],min\{f[i][t][k-1]+f[t][j][0]\}(1\le t\le n))$$

我们要预处理出$f[i][j][0]$,即$m$种车中从$i$城到$j$城所需的最短时间。我们记$w[i][j][k]$为第$i$种车从$j$城到$k$城所需的最短时间,则$w[i][j][k]=min\{w[i][j][t]+w[i][t][k]\}(1\le t\le n)$,然后可得$f[j][k][0]=min\{w[i][j][k]\}(1\le i\le m)$。

初始值:$w$读入,$f$无穷大。

答案:$min\{f[s][t][i]\}(0\le i\le k)$

代码实现过程中要注意循环的嵌套顺序!

【代码实现】

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #define g() getchar()
 7 #define rg register
 8 #define go(i,a,b) for(rg int i=a;i<=b;i++)
 9 #define back(i,a,b) for(rg int i=a;i>=b;i--)
10 #define db double
11 #define ll long long
12 #define il inline
13 #define pf printf
14 #define sf scanf
15 #define mem(a,b) memset(a,b,sizeof(a))
16 using namespace std;
17 int fr(){
18     int w=0,q=1;
19     char ch=g();
20     while(ch<'0'||ch>'9'){
21         if(ch=='-') q=-1;
22         ch=g();
23     }
24     while(ch>='0'&&ch<='9') w=(w<<1)+(w<<3)+ch-'0',ch=g();
25     return w*q;
26 }
27 const int N=52;
28 const ll INF=1e10+999999999;
29 int n,m,r;
30 ll f[N][N][N],w[N][N][N],ans;
31 int main(){
32     //freopen("","r",stdin);
33     //freopen("","w",stdout);
34     while(sf("%d%d%d",&n,&m,&r)!=EOF){
35         mem(f,63);
36         go(i,1,m) go(j,1,n) go(k,1,n) w[i][j][k]=fr();
37         //按照输入顺序嵌套循环
38         go(i,1,m) go(t,1,n) go(j,1,n) go(k,1,n)
39             w[i][j][k]=min(w[i][j][k],w[i][j][t]+w[i][t][k]);
40         //以t为中间点找最小值,Floyd最短路
41         go(j,1,n) go(k,1,n) go(i,1,m)
42             f[j][k][0]=min(f[j][k][0],w[i][j][k]);
43         //对于固定的两个城市j,k,枚举m种车旭找最短时间
44         go(k,1,n) go(t,1,n) go(i,1,n) go(j,1,n)
45             f[i][j][k]=min(f[i][j][k],f[i][t][k-1]+f[t][j][0]);
46         //DP,注意循环嵌套的顺序!
47         while(r--){
48             rg int s=fr(),t=fr(),k=fr();
49             if(k>n) k=n;ans=INF;
50             go(i,0,k) ans=min(ans,f[s][t][i]);
51             pf("%lld\n",ans);
52         }
53     }
54     return 0;
55 }
代码戳这里
posted @ 2019-08-28 11:08  小叽居biubiu  阅读(153)  评论(0编辑  收藏  举报