完全最短路径问题Floyd算法 pku 1125 Stockbroker Grapevine

题目链接:

http://acm.pku.edu.cn/JudgeOnline/problem?id=1125

 

理解题意最关键的一句话:

Your task will be to write a program that tells you which stockbroker to choose as your

starting point for the rumour, as well as the time it will take for the rumour to spread

throughout the stockbroker community. This duration is measured as the time needed for the

last person to receive the information.

 

 

 

本题 0测试 直接 编译提交AC三步到位!!!^_^~~~

//策略:
//先用Floyd算法求出从每一个顶点到其他所有顶点的最短路径的长度
//再保存每个顶点到其他所有顶点的最大距离到dist[]数组中
//找出数组的最小值
//如果最小值为Inf则存在不可到达顶点.否则输出该路径长度
#include <stdio.h>

#define Inf 1<<20
#define max_n 105
#define MIN(x,y) ((x) < (y) ? (x) : (y))
#define MAX(x,y) ((x) > (y) ? (x) : (y))

int arc[max_n][max_n];
int dist[max_n];

//k >= 1时:
//d(0)[i][j] = w[i][j];
//d(k)[i][j] = min(d(k - 1)[i][j],d[k - 1][i][k] + d[k - 1][k][j])
//也就是说:
//当中间顶点的最大序号从k - 1增加到k的时候
//(i,j)的距离是原来的距离与中间顶点的最大序号为k的2段(i,k),(k,j)的和的最小值
//其中这2段的中间顶点的最大序号为k - 1,因为对他们而已k是末端顶点

void Floyd(int n){
	int i,j,k;
	for(k = 1;k <= n;k++)
		for(i = 1;i <= n;i++)
			for(j = 1;j <= n;j++)
				arc[i][j] = MIN(arc[i][j],arc[i][k] + arc[k][j]);
}

int main(){
	int n;
	while(scanf("%d",&n),n){
		int i,j,k;
		for(i = 1;i <= n;i++)
			for(j = 1;j <= n;j++){
				if(i == j)
					arc[i][j] = 0;
				else
					arc[i][j] = Inf;
			}
		int u,cost;
		for(i = 1;i <= n;i++){
			scanf("%d",&k);
			for(j = 1;j <= k;j++){
				scanf("%d%d",&u,&cost);
				arc[i][u] = cost;
			}
		}
		Floyd(n);
		int max_d;
		for(i = 1;i <= n;i++){
			max_d = -1;
			for(j = 1;j <= n;j++)
				max_d = MAX(max_d,arc[i][j]);
			dist[i] = max_d;
		}
		int min_d = Inf,fastest;
		for(i = 1;i <= n;i++)
			//min_d = MIN(min_d,dist[i]);
			if(dist[i] < min_d){
				min_d = dist[i];
				fastest = i;
			}
		if(min_d == Inf)
			printf("disjoint/n");
		else
			printf("%d %d/n",fastest,min_d);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值