题目描述
现在是晚餐时间,而母牛们在外面分散的牧场中。
Farmer John 按响了电铃,所以她们开始向谷仓走去。 你的工作是要指出哪只母牛会最先到达谷仓(在给出的测试数据中,总会有且只有一只最快的母牛)。在挤奶的时候(晚餐前),每只母牛都在她自己的牧场上,一些牧场上可能没有母牛。
每个牧场由一条条道路和一个或多个牧场连接(可能包括自己)。有时,两个牧场(可能是字母相同的)之间会有超过一条道路相连。至少有一个牧场和谷仓之间有道路连接。因此,所有的母牛最后都能到达谷仓,并且母牛总是走最短的路径。当然,母牛能向着任意一方向前进,并且她们以相同的速度前进。牧场被标记为 a … z 和 A … Y ,在用大写字母表示的牧场中有一只母牛,小写字母中则没有。 谷仓的标记是 Z ,注意没有母牛在谷仓中。
注意 m 和 M 不是同一个牧场。
输入格式
第一行一个整数 P (1 ≤ P ≤ 10,000 ),表示连接牧场(谷仓)的道路的数目。
接下来 P 行,每行用空格分开的两个字母和一个正整数:被道路连接牧场的标号和道路的长度
输出格式
单独的一行包含二个项目:最先到达谷仓的母牛所在的牧场的标号,和这只母牛走过的路径的长度
#include<bits/stdc++.h>
using namespace std;
const int maxn = 100001;
int h[maxn], tot = -1;
int d[maxn];
bool vis[maxn];
struct Edge {
int to, next, len;
} edge[maxn * 2];
void addEdge(int x, int y, int len) {
edge[++tot] = (Edge){y, h[x], len};
h[x] = tot;
}
queue<int> q;
void SPFA(int start) {
memset(d, 0x3f, sizeof(d));
q.push(start);
d[start] = 0;
vis[start] = 1;
while (!q.empty()) {
int u = q.front();
q.pop();
vis[u] = 0;
for (int i = h[u]; i != -1; i = edge[i].next) {
int to = edge[i].to;
int len = edge[i].len;
if (d[to] > d[u] + len) {
d[to] = d[u] + len;
if (!vis[to]) {
q.push(to);
}
}
}
}
}
int main() {
int p;
scanf("%d", &p);
memset(h, -1, sizeof(h));
for (int i = 1; i <= p; i++) {
char x[2], y[2];
int len;
scanf("%s%s%d", x, y, &len);
addEdge(x[0], y[0], len);
addEdge(y[0], x[0], len);
}
SPFA('Z');
int ans_len = 1e9;
char ans;
for (char i = 'A'; i < 'Z'; i++) {
if (d[i] < ans_len) {
ans_len = d[i];
ans = i;
}
}
printf("%c %d", ans, ans_len);
return 0;
}