码迷,mamicode.com
首页 > 其他好文 > 详细

codevs 1243 网络提速

时间:2017-05-13 19:59:56      阅读:133      评论:0      收藏:0      [点我收藏+]

标签:using   efi   last   names   queue   max   没有   des   int   

1243 网络提速

时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold
题目描述 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次。

#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
#define maxn 55
#define inf 999999999.99
struct Edge {
	int u,v,next;
	double w;
	Edge(int u=0,int v=0,double w=0,int next=0):
		u(u),v(v),w(w),next(next) {}
}edge[maxn*maxn];
int head[maxn],cnt=0,record[maxn],n,m,num=0;
double dis[maxn],value[maxn*maxn];
bool inq[maxn];
inline void Add_edge(int u,int v,double w) {
	edge[++cnt]=Edge(u,v,w,head[u]);
	head[u]=cnt; return;
}
bool cmp(double a,double b){return a>b;}
void SPFA(int s=1,int t=n) {
	for(int i=1;i<=n;i++) dis[i]=inf,inq[i]=false;
	queue<int>q;
	q.push(s);inq[s]=true;dis[s]=0.0;
	while(!q.empty()) {
		int u=q.front();q.pop();inq[u]=false;
		for(int i=head[u];i;i=edge[i].next) {
			int v=edge[i].v;
			if(dis[v]>dis[u]+edge[i].w) {
				dis[v]=dis[u]+edge[i].w;
				if(!inq[v]) {
					q.push(v);
					inq[v]=true;
				}
				record[v]=i;
			}
		}
	}
	return;
}
int main() {
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++) {
			double w;
			scanf("%lf",&w);
			if(w!=0.0) Add_edge(i,j,w);
		}
	int end=n;double ans=0.0;SPFA();
	while(end!=1) {
		int last=record[end];
		value[++num]=edge[last].w;
		end=edge[last].u;
	}
	sort(value+1,value+num+1,cmp);
	while(m--) {
		value[1]=value[1]*(0.5);
		sort(value+1,value+num+1,cmp);
	}
	for(int i=1;i<=num;i++) ans+=value[i];
	printf("%.2lf",ans);
	return 0;
}

  可能麻烦了一点,但是AC了。OvO

 

codevs 1243 网络提速

标签:using   efi   last   names   queue   max   没有   des   int   

原文地址:http://www.cnblogs.com/NuclearSubmarines/p/6849972.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!