MPI Maelstrom

题目链接
可以不看下面的中文翻译,翻译后面我给出了题目大体意思:
题目中文:
比特最近交付了他们的新超级计算机,一台32处理器的阿波罗奥德赛分布式共享内存机,带有分层通信子系统。瓦伦丁·麦基的研究顾问杰克·斯威格特(JackSwigert)要求她对新系统进行基准测试。
“由于阿波罗号是一个分布式共享内存机,内存访问和通信时间并不统一,”瓦伦丁告诉Swigert。共享同一内存子系统的处理器之间的通信速度很快,但不在同一子系统上的处理器之间的通信速度较慢。阿波罗号和我们实验室的机器之间的通讯还很慢。
Apollo的消息传递接口(MPI)的端口如何工作?斯威格特问。“不太好,”瓦伦丁回答。要将消息从一个处理器广播到所有其他N-1处理器,它们只需执行一个N-1发送序列。这真的会连载事情并破坏性能。”你能做些什么来解决这个问题吗?
“是的,”瓦伦丁笑着说。有。旦第一个处理器将消息发送给另一个处理器,这两个处理器就可以同时向其他两个主机发送消息。然后会有四个主机可以发送,等等。
啊,所以你可以用二叉树来做广播!不是真正的二叉树——我们的网络有一些我们应该利用的特殊特性。我们拥有的接口卡允许每个处理器同时向与其相连的任何数量的其他处理器发送消息。然而,消息不一定同时到达目的地
——这涉及到通信成本。一般来说,我们需要考虑网络拓扑中每个链路的通信成本,并相应地计划,以尽量减少进行广播所需的总时间。
输入
输入将描述连接n个处理器的网络的拓扑结构。输入的第一行将是n,处理器的数量,这样1<=n<=100。
输入的其余部分定义了一个邻接矩阵a。邻接矩阵是方形的,大小为n x n。每个条目都将是一个整数或字符x。a(i,j)的值表示直接从节点i向节点j发送消息的费用。a(i,j)的值x表示消息不能直接从节点I发送到节点J。
请注意,对于向其自身发送消息的节点,不需要网络通信,因此a(i,i)=0表示1<=i<=n。此外,您可以假定网络是无向的(消息可以以相等的开销向任意方向发送),因此a(i,j)=a(j,i)。因此,只提供(严格地)A的下三角形部分上的条目。
程序的输入将是a的下三角形部分。也就是说,输入的第二行将包含一个条目a(2,1)。下一行将包含两个条目,一个(3,1)和一个(3,2),依此类推。
输出
您的程序应该输出从第一个处理器向所有其他处理器广播消息所需的最短通信时间

题目大意:
地图上有n个点,有一个点是信号发射站,其他站有接受信号和传播信号的作用。且信号发射后,会向各个点传播。
问信号什么时候可以覆盖到所有的点。

解题思路:求出第一个点到第2~n个点的最短路径,然后从这些最短路径里面选出最大的值,就是题目的答案。

代码里面有详细的注释:
Bellman算法,无向图

//Bellman_ford算法,求第一个点到其它点的最短路,并筛选出这些最短路里的最大值。
//无向图,因为给点a和b两点所需的时间,那么a-》b和b-》a所需的时间相同。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node 
{
	int u,v,w;
}e[10010];
int dis[102];
int book[102];
const int inf=0x3f3f3f3f;
//解决输入问题
int solve(char a[])
{
	if(a[0]=='x') return inf;
	
	int sum=0;
	for(int i=0;a[i]!='\0';i++)
	sum=sum*10 + a[i]-'0';
	
	return sum;
}
int main()
{
	int n,c,f,ans;
	char temp[13];
	scanf("%d",&n);
	getchar();
	
	c=0;
	for(int i=2;i<=n;i++)
	for(int j=1;j<i;j++)
	{
	//虽然是无向图,但是这里只保留一条边的信息,具体操作看下面的核心算法
		e[++c].u=i;
		e[c].v=j;
		scanf("%s",temp);
		e[c].w=solve(temp);
	}
	
	dis[1]=0;
	for(int i=2;i<=n;i++)
	dis[i]=inf;
	
	for(int i=1;i<=n;i++)
	{
		f=0;
		//说一下book[]数组的作用
		//在这n次更新中,可能更新了m(m《n)次,就使得第一个点到其它的信息
		//都是最小值了,那么,dis数组里面的内容就不会变化了,book数组保留了
		//dis数组里面的内容,这样就可以检查到dis数组里面的内容没有更新了。
		for(int j=1;j<=n;j++) book[j]=dis[j];
		
		for(int j=1;j<=c;j++)
		{
			if(dis[e[j].v] > dis[e[j].u] + e[j].w)
			dis[e[j].v]=dis[e[j].u] + e[j].w;
		}
		
		for(int j=1;j<=c;j++)
		{
			if(dis[e[j].u] > dis[e[j].v] + e[j].w)
			dis[e[j].u]=dis[e[j].v] + e[j].w;
		}
		
		for(int j=1;j<=n;j++)
		{
			if(book[j]!=dis[j])
			f=1;
		}
		
		if(!f) break;
	}
	
	ans=0;
	for(int i=1;i<=n;i++)
	ans=max(ans,dis[i]);
	
	printf("%d\n",ans);
	return 0;	
} 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值