拿到题我一看题, 大概是考我们无向图 (尽管题目说的是树) 的最短路径吧
正当我打到一半时, dalao 智慧草 (这个人可是个神仙) 忍不住了:
"floyd 时间复杂度 O(n^3)再看看数据范围 n=10^3 时肯定得超时, 这题正解是 LCA 不倍增也行"
本菜鸡偏就不信, 我就要用 floyd 做, 哼哼.
很快敲完了一个模板, 代码:
- #include <iostream>
- using namespace std;
- int n, m, x, y, z;
- int edge[1001][1001];
- int main() {
- cin>> n>> m;
- for (int i = 1; i <= n; i++) {
- for (int j = 1; j <= n; j++) {
- edge[i][j] = (i == j) ? 0 : 0x3f3f3f3f;
- }
- }
- for (int i = 1; i <= n - 1; i++) {
- cin>> x>> y>> z;
- edge[x][y] = edge[y][x] = z;
- }
- for (int k = 1; k <= n; k++) {
- for (int i = 1; i <= n; i++) {
- for (int j = 1; j <= n; j++) {
- edge[i][j] = min(edge[i][j], edge[i][k] + edge[k][j]);
- }
- }
- }
- for (int i = 1; i <= m; i++) {
- cin>> x>> y;
- cout <<edge[x][y] << endl;
- }
- return 0;
- }
交上去 80, 海星
然后就是优化了
首先第 i 个节点必须不是第 k 个节点, 不然自己到自己吃饱撑着(i!=k)
其次第 i 个节点到第 k 个节点必须有边, 毕竟这些奶牛的关系是像树一样的(t!=inf)
之后就是利用矩阵的对称性, 只使用下三角(可有可无)
优化完毕(因为我只使用了下三角, 所以我的输出得注意一下)
AC 代码(160ms 挺慢的):
- #include <cstdio>
- int n, m, x, y, z;
- int edge[1001][1001];
- int min(int x, int y) { return (x < y) ? x : y; }
- int main() {
- scanf("%d %d", &n, &m);
- for (int i = 1; i <= n; i++) {
- for (int j = 1; j <= n; j++) {
- edge[i][j] = (i == j) ? 0 : 0x3f3f3f3f;
- }
- }
- for (int i = 1; i <= n - 1; i++) {
- scanf("%d %d %d", &x, &y, &z);
- edge[x][y] = edge[y][x] = z;
- }
- for (int k = 1; k <= n; k++) {
- for (int i = 1; i <= n; i++) {
- if (k != i) {
- int t = (k < i) ? edge[i][k] : edge[k][i];
- if (t == 0x3f3f3f3f)
- continue;
- for (int j = 1; j <= min(k, i); j++) {
- edge[i][j] = min(edge[i][j], t + edge[k][j]);
- }
- for (int j = k + 1; j <= i; j++) {
- edge[i][j] = min(edge[i][j], t + edge[j][k]);
- }
- }
- }
- }
- for (int i = 1; i <= m; i++) {
- scanf("%d %d", &x, &y);
- printf("%d\n", edge[x][y] == 0x3f3f3f3f ? edge[y][x] : edge[x][y]);
- }
- return 0;
- }
[题解] [Usaco2008 Oct]牧场行走
来源: http://www.bubuko.com/infodetail-3386594.html