【拆点+最短路】网络提速

传送门:CodeVS1243


拆点经典题哦!

贪心显然会挂掉。

观察数据发现计算机都很少,加速器也很少,于是就拆点,

把从1到计算机i的dis拆成一共花了j台加速器后从1到i,

然后最短路跑一发就好了


以下代码(SPFA版):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define INF 10000000
int n,m,t,w,x,y;
double z,a[80][80][30],f[80][30];
struct que{ int x,js;}q[300000];
void spfa(){
t=0; w=1;
q[1].x=1; q[1].js=0;
while (t<w){
t++;
x=q[t].x; y=q[t].js;
for (int i=1;i<=n;i++)
if (a[x][i][0]!=INF)
for (int j=y;j<=m;j++)
if (f[i][j]>f[x][y]+a[x][i][j-y]){
f[i][j]=f[x][y]+a[x][i][j-y];
w++;
q[w].x=i; q[w].js=j;
}
}
}
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++){
scanf("%lf",&a[i][j][0]);
if (a[i][j][0]==0)
for (int k=0;k<=m;k++) a[i][j][k]=INF;
else
for (int k=1;k<=m;k++) a[i][j][k]=a[i][j][k-1]/2;
}
for (int i=2;i<=n;i++)
for (int j=0;j<=m;j++)
f[i][j]=INF;
spfa();
printf("%.2f",f[n][m]);
return 0;
}