AcWing 1375. 奶牛回家
原题链接
简单
作者:
白墙
,
2021-04-02 18:34:27
,
所有人可见
,
阅读 444
1、这题求得是什么?需要确定哪一头奶牛最快到达牛棚,输出他所在农场得标记和它走过得路径。等价于什么?
等价于求最小距离
2、这道题得性质是什么?有重边、自环、无向图、正权边
3、如何抽象图?如何用函数表示?
每个牧场之间都有至少一条道路相连,每个牧场也有自己道路。牧场和牛棚有道路相连。每个牧场都可以沿道路
返回牛棚。
起点用z表示,终点是各个牧场。最后取最小值。
如何处理各个有牛和无牛的牧场?如果无牛,则直接可以用dijkstra求了。
4、是否能够用dijkstra求?
st[N]已经确定最小距离的牧场。dist[N]到牛棚的最短距离。d[N][N];
5、注意题目的数据范围
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int N = 1e3 + 1000;
bool st[N * 2];
int dist[N * 2], g[N * 2][N * 2];
int n;
void dijkstra() {
memset (dist, 0x3f, sizeof dist);
dist['Z'] = 0;
for (int i = 0; i <= n * 2; i ++) {
int t = -1;
for (int j = 'A'; j <= 'Z'; j ++)
if (!st[j] && (t == -1 || dist[j] < dist[t])) t = j;
for (int j = 'a'; j <= 'z'; j++)
if (!st[j] && (t == -1 || dist[j] < dist[t])) t = j;
st[t] = true;
for (int j = 'A'; j <= 'Z'; j++) {
dist[j] = min (dist[j], dist[t] + g[t][j]);
}
for (int j = 'a'; j <= 'z'; j ++)
dist[j] = min (dist[j], dist[t] + g[t][j]);
}
}
int main () {
cin >> n;
memset (g, 0x3f, sizeof g);
for (int i = 0; i < n; i++) {
char a, b;
int c;
cin >> a >> b >> c;
g[a][b] = g[b][a] = min (g[a][b], c);
}
dijkstra();
char c;
int res = 0x3f3f3f3f;
for (int i = 'A'; i < 'Z'; i ++) {
if (res > dist[i]) {
res = dist[i];
c = i;
}
}
printf ("%c %d", c, res);
return 0;
}
为什么无牛,可以直接用dijkstra求
这里表示dist[j]表示的是从牛棚到牧场j的最短距离。我们这个问题可以转化程单源最短问题i,即从牛棚开始,到所有牧场的最短距离。这里需要更新没有牛的牧场,因为牛会经过这些地方,也就是说这些地方相当于有牛,如果不更新没有牛的地方,那么就会出现断开的情况,即有些牛无法通过牧场走到牛棚。当然最后我们的答案是在有牛的牧场选的。