题目描述 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
数据范围及提示 Data Size & Hint
分类标签 Tags 点此展开
AC代码:
#include<bits/stdc++.h> #define pir pair<int,int> using namespace std; const int N=1e3+10; vector<int>e[N]; vector<int>g[N]; int n,m,S,T; int dis[N],qq[N]; bool vis[N]; void djc(){ for(int i=1;i<=n;i++) dis[i]=0x3f3f3f3f; dis[S]=0; priority_queue<pir,vector<pir >,greater<pir> >q; q.push(make_pair(dis[S],S)); while(!q.empty()){ pir t=q.top();q.pop(); int h=t.second; if(vis[h]) continue; vis[h]=1; for(int i=0;i<e[h].size();i++){ int v=e[h][i]; if(!vis[v]&&dis[v]>dis[h]+g[h][i]){ dis[v]=dis[h]+g[h][i]; qq[v]=h; q.push(make_pair(dis[v],v)); } } } } void out(){ priority_queue<double >q; int x=n; while(x){ double t=dis[x]-dis[qq[x]]; q.push(t); x=qq[x]; } for(int i=1;i<=m;i++){ double h=q.top();q.pop(); h/=2; q.push(h); } double ans=0; while(!q.empty()){ ans+=q.top();q.pop(); } printf("%.2lf",ans); } int main(){ scanf("%d%d",&n,&m);S=1;T=n; for(int i=1,x;i<=n;i++){ for(int j=1;j<=n;j++){ scanf("%d",&x); if(!x) continue; e[i].push_back(j);g[i].push_back(x); e[j].push_back(i);g[j].push_back(x); } } djc(); out(); return 0; }