Bessie Come Home

题目描述:

It's dinner time, and the cows are out in their separate pastures. Farmer John rings the bell so they will start walking to the barn. Your job is to figure out which one cow gets to the barn first (the supplied test data will always have exactly one fastest cow).

Between milkings, each cow is located in her own pasture, though some pastures have no cows in them. Each pasture is connected by a path to one or more other pastures (potentially including itself). Sometimes, two (potentially self-same) pastures are connected by more than one path. One or more of the pastures has a path to the barn. Thus, all cows have a path to the barn and they always know the shortest path. Of course, cows can go either direction on a path and they all walk at the same speed.

The pastures are labeled `a'..`z' and `A'..`Y'. One cow is in each pasture labeled with a capital letter. No cow is in a pasture labeled with a lower case letter. The barn's label is `Z'; no cows are in the barn, though.

输入输出格式:

INPUT FORMAT

Line 1:

Integer P (1 <= P <= 10000) the number of paths that interconnect the pastures (and the barn)

Line 2..P+1:

Space separated, two letters and an integer: the names of the interconnected pastures/barn and the distance between them (1 <= distance <= 1000)

SAMPLE INPUT (file comehome.in)

5
A d 6
B d 3
C e 9
d Z 8
e Z 3

OUTPUT FORMAT

A single line containing two items: the capital letter name of the pasture of the cow that arrives first back at the barn, the length of the path followed by that cow.

SAMPLE OUTPUT (file comehome.out)

B 11

题目大意:

现在是晚餐时间,而母牛们在外面分散的牧场中。 农民约翰按响了电铃,所以她们开始向谷仓走去。 你的工作是要指出哪只母牛会最先到达谷仓(在给出的测试数据中,总会有且只有一只最快的母牛)。 在挤奶的时候(晚餐前),每只母牛都在她自己的牧场上,一些牧场上可能没有母牛。 每个牧场由一条条道路和一个或多个牧场连接(可能包括自己)。 有时,两个牧场(可能是字母相同的)之间会有超过一条道路相连。 至少有一个牧场和谷仓之间有道路连接。 因此,所有的母牛最后都能到达谷仓,并且母牛总是走最短的路径。 当然,母牛能向着任意一方向前进,并且她们以相同的速度前进。 牧场被标记为'a'..'z'和'A'..'Y',在用大写字母表示的牧场中有一只母牛,小写字母中则没有。 谷仓的标记是'Z',注意没有母牛在谷仓中。

输入格式

第 1 行: 整数 P(1<= P<=10000),表示连接牧场(谷仓)的道路的数目。

第 2 ..P+1行: 用空格分开的两个字母和一个整数:

被道路连接牧场的标记和道路的长度(1<=长度<=1000)。

输出格式

单独的一行包含二个项目: 最先到达谷仓的母牛所在的牧场的标记,和这只母牛走过的路径的长度。

解题思路:

这个题目需要用迪杰斯特拉算法求最短路径,把Z当做起点,到每一个牧场的距离需要求出来,还有就是题目读起来有一点绕,需要画图来理解,自己比较懒,写文章只是怕自己以后忘记了,所以就不在电脑上绘图了,还有我是用邻接矩阵来存储图的,这也是一个点,看代码的时候要注意,迪杰斯特拉用的是教科书原版没有任何修改,题目是用A-Z,a-z来表示的,参考网上的代码修改为了数字。

#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#include <set>
#include <cstdio>
#include <algorithm>
#include<cmath>
#include<limits.h>
using namespace std;
int dis[100], tu[100][100];//从Z出发的dis值和邻接矩阵
int p, vis[100];//道路数目,节点标记
char r;
void save(int x, int y, int w) {//用邻接矩阵表示,邻接矩阵是对称的
	if (tu[x][y] == 0) {
		tu[x][y] = w;
		tu[y][x] = w;
	}
	if (w < tu[x][y]) {//读入的第二条边比第一条边权值小
		tu[x][y] = w;
		tu[y][x] = w;
	}
}
void Dijkstra() {//Dijkstra寻找单源最短路径
	int u, min;
	for(int i = 1; i <= 51; i++) {
		min = INT_MAX;
		//下面这个for循环的功能类似冒泡排序,目的是找到未访问节点中d[j]值最小的那个节点,
		//作为下一个访问节点,用u标记
		for (int j = 1; j <= 51; j++) {
			if (vis[j] == 0 && dis[j] < min) {
				min = dis[j];
				u = j;
			}
		}
		vis[u] = 1;//置1代表节点被访问过了
		for (int v = 1; v <= 51; v++) {//不断的更新距离
			if (dis[v] > dis[u] + tu[u][v] && vis[v] == 0 && tu[u][v] < INT_MAX) {
				dis[v] = dis[u] + tu[u][v];
			}
		}
	}
}
int main() {
	freopen("D:\\test.in", "r", stdin);
	freopen("D:\\test.out", "w", stdout);
	scanf("%d", &p);
	for (int i = 1; i <= 52; i++) {//初始化图设置为距离不可达
		for (int j = 1; j <= 51; j++) {
			tu[i][j] = INT_MAX;
		}
	}
	vis[52] = 1;
	for (int i = 1; i <= p; i++) {
		//读入数据
		char x, y;
		int xx,yy,c;//权值
		scanf("\n%c %c %d", &x, &y, &c);
		if (x >= 'a' && x <= 'z') {//把牧场字母转换成数字
			xx = x - 'a' + 1;
		}
		else
		{
			xx = x - 'A' + 27;
		}
		if (y >= 'a' && y <= 'z') {
			yy = y - 'a' + 1;
		}
		else {
			yy = y - 'A' + 27;
		}
		save(xx,yy,c);//进行存图操作
	}
	for (int i = 1; i <= 51; i++) {
		dis[i] = tu[52][i];
	}
	Dijkstra();
	int hh = INT_MAX, point;
	for (int i = 1; i <= 51; i++) {//找出最短的距离和牧场
		if (dis[i] < hh && i >= 27) {
			hh = dis[i];
			point = i;
		}
	}
	printf("%c %d\n", point - 27 + 'A', hh);
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值