CJOJ 2422 [USACO Mar08] 奶牛跑步

奶牛跑步

Description

Bessie准备用从牛棚跑到池塘的方法来锻炼. 但是因为她懒,她只准备沿着下坡的路跑到池塘,然后走回牛棚.

Bessie也不想跑得太远,所以她想走最短的路经. 农场上一共有M(1<=M<=10,000)条路,每条路连接两个用1..N(1<=N<=1000)标号的地点. 更方便的是,如果X>Y,则地点X的高度大于地点Y的高度. 地点N是Bessie的牛棚;地点1是池塘.

很快, Bessie厌倦了一直走同一条路.所以她想走不同的路,更明确地讲,她想找出K(1<=K<=100)条不同的路经.为了避免过度劳累,她想使这K条路径为最短的K条路径.

请帮助Bessie找出这K条最短路经的长度.你的程序需要读入农场的地图, 一些从Xi到Yi的路径和它们的长度(Xi,Yi,Di).
所有(Xi,Yi,Di) 满足( 1<=Yi<Xi; Yi<Xi<=N, 1<=Di<=1,000,000 ).

Input

第1行: 3个数: N,M,K
第2..M+1行: 第 i+1行包含3个数 Xi,Yi,Di, 表示一条下坡的路.

Output

第1..K行: 第i行包含第i最短路径的长度,或−1如果这样的路径不存在.如果多条路径有同样的长度,请注意将这些长度逐一列出.

Sample Input

5 8 7
5 4 1
5 3 1
5 2 1
5 1 1
4 3 4
3 1 1
3 2 1
2 1 1

Sample Output

1
2
2
3
6
7
-1

Hint

【样例解释】
路径分别为(5−1),(5−3−1),(5−2−1),(5−3−2−1),(5−4−3−1),(5−4−3−2−1)

Source

动态规划, 图论, A*搜索, k短路

Solution

这道题的标程是A*搜索,然而在网上看到了一个跑的飞快的神奇的递推,于是妥妥的放弃了A*……

对与插入的每一个点(0号~n - 1号)我们可以记录一个数组h[i][j],表示i号点到n - 1号点的第j小路的长度,那么最后答案存于h[0][i]中,递推方程显然有: 

for (int i = 0; i < k; ++i)//更新第i小的边
    if (h[x][t1] + d < h[y][t2]) temp[i] = h[x][t1++] + d;//用其父边更新最短距离(先到父亲再从父亲去n - 1)
    else temp[i] = h[y][t2++];//用自己更新(直接从自己去n - 1)
for (int i = 0; i < k; ++i) h[y][i] = temp[i];//记录第i小路径

对于初始化,除了从n - 1到n - 1的第1小边为0外,其他值都初始化为最大值(即不存在)

Code

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <stack>
#include <map>
#include <vector>
#include <queue>
#define LL long long
using namespace std;

inline int gi() {
  char cj = getchar();
  int ans = 0, f = 1;
  while (cj < '0' || cj > '9') {
    if (cj == '-') f = -1;cj = getchar();
  }
  while (cj >= '0' && cj <= '9') ans = ans * 10 + cj - '0', cj = getchar();
  return f * ans;
}

struct node {
  int to, nxt, w;
} e[10010];
int n, m, k, a, b, c, head[1010], cnt, h[1010][110], temp[110];

inline void add(int a, int b, int c) {
  e[++cnt].nxt = head[a], e[cnt].to = b, e[cnt].w = c, head[a] = cnt;
}

inline void update(int x, int y, int d) {
  int t1 = 0, t2 = 0;
  for (int i = 0; i < k; ++i)
    if (h[x][t1] + d < h[y][t2]) temp[i] = h[x][t1++] + d;
    else temp[i] = h[y][t2++];
  for (int i = 0; i < k; ++i) h[y][i] = temp[i];
}

int main() {
  freopen("cowjog.in", "r", stdin);
  freopen("cowjog.out", "w", stdout);
  n = gi(), m = gi(), k = gi();
  for (int i = 0; i < m; ++i) {
    a = gi(), b = gi(), c = gi();
    add(a - 1, b - 1, c);
  }
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < k; ++j)
      h[i][j] = 1e9; h[n - 1][0] = 0;
  for (int i = n - 1; i >= 0; --i)
    for (int j = head[i]; j; j = e[j].nxt)
      update(i, e[j].to, e[j].w);
  for (int i = 0; i < k; ++i)
    printf("%d\n", h[0][i] == 1e9 ? -1 : h[0][i]);
  return 0;
}

Summary

考试的时候完全不会写(之前没有练过A*搜索),就直接输出-1,果然没有一个这种点……
注意递推的时候每使用一次h[i][t1]或h[i][t2]都要将t1++或t2++,因为每个大小的值不能重复


### USACO Competition Problem Solutions for Cow Games In the context of USACO competitions, problems involving cows often require a blend of algorithmic thinking and mathematical insight. For instance, one notable problem involves Farmer John providing hay to his cows on different days with varying quantities[^3]. This type of scenario can be modeled using dynamic programming or greedy algorithms depending on what is asked. For specific game-related challenges featuring cows within USACO contests, consider an example where cows play games that involve strategic decision-making under given constraints. These scenarios frequently test contestants' ability to apply concepts like graph theory, number manipulation, and optimization techniques effectively. A relevant exercise from similar competitive coding platforms includes dealing with round numbers which have properties making them interesting subjects for computational puzzles[^2]: ```python def count_round_numbers(n): binary_representation = bin(n)[2:] zero_count = binary_representation.count('0') return zero_count >= len(binary_representation) / 2 ``` This function checks whether a number has at least as many zeros as ones in its binary representation—a concept sometimes explored through playful contexts such as virtual cow activities designed around numerical patterns. To tackle these kinds of tasks successfully: - Understand all rules governing how elements interact. - Identify efficient ways to represent data structures involved. - Develop strategies based on observed trends or established theories applicable to the situation described.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值