题目描述 Description
某学校的校园网由n(1<=n<=50)台计算机组成,计算机之间由网线相连,如图5。其中顶点代表计算机,边代表网线。正如你所见,不同网线的传输能力不尽相同,例如计算机1与计算机2之间传输信息需要34秒,而计算机2与计算机3之间的传输信息只要10秒。计算机1与计算机5之间传输信息需要44秒,途径为机1到机3到机5。
现学校购买了m(1<=m<=10)台加速设备,每台设备可作用于一条网线,使网线上传输信息用时减半。多台设备可用于同一条网线,其效果叠加,即用两台设备,用时为原来的1/4,用三台设备,用时为原来的1/8。如何合理使用这些设备,使计算机1到计算机n传输用时最少,这个问题急需解决。校方请你编程解决这个问题。例如图5,若m=2,则将两台设备分别用于1-3,3-5的线路,传输用时可减少为22秒,这是最佳解。
输入描述 Input Description
第一行先输入n,m。以下n行,每行有n个实数。第i行第j列的数为计算机i与计算机j之间网线的传输用时,0表示它们之间没有网线连接。注意输入数据中,从计算机1到计算机n至少有一条网路。
输出描述 Output Description
输出计算机1与计算机n之间传输信息的最短时间。(保留两位小数)
样例输入 Sample Input
5 2
0 34 24 0 0
34 0 10 12 0
24 10 0 16 20
0 12 16 0 30
0 0 20 30 0
样例输出 Sample Output
22.00
这里写题解看到点这么少显然是拆点啊每个店拆成m个,同理每条边拆成2*m^2/2条因为不能向上构边
不废话了:#include<iostream>
#include<cstdio>
#include<climits>
#include<cmath>
#include<queue>
using namespace std;
int n,m;
bool flag[51][11];
struct node
{int num;
int h;
};
double dis[51][11];
double chu(int x,int y)
{ double k=1.0;
for(int i=1;i<=y;i++)
k=k*2.0;
return x/k;
}
double map[51][11][51][11];
int main()
{ cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{int x; scanf("%d",&x);
for(int k=0;k<=m;k++)
for(int p=k;p<=m;p++)
map[i][k][j][p]=chu(x,p-k);
}
queue<node> q;
q.push((node){1,0});flag[1][0]=1;
while(!q.empty())
{ node k=q.front(); q.pop();
flag[1][0]=0;
for(int i=1;i<=n;i++)
for(int j=k.h;j<=m;j++)
{if(map[k.num][k.h][i][j]!=0&&(dis[i][j]==0||dis[i][j]>dis[k.num][k.h]+map[k.num][k.h][i][j]))
{dis[i][j]=dis[k.num][k.h]+map[k.num][k.h][i][j];
if(flag[i][j]==0)
{flag[i][j]=1;
q.push((node){i,j});
}
}
}
}
printf("%.2f",dis[n][m]);
return 0;
}