传送门: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; }
|