前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【小码匠自习室】摸鱼被抓:ABC 073 - D - joisino's travel

【小码匠自习室】摸鱼被抓:ABC 073 - D - joisino's travel

作者头像
小码匠
发布2023-03-06 14:33:48
2930
发布2023-03-06 14:33:48
举报
文章被收录于专栏:小码匠和老码农

10分钟而已

昨晚那道题【P6464 传送门】搞了3个小时,都没过样例,很受伤。。。

今天刷完本题后,就摸了10分钟,被抓了个现行。太欺负小孩了。。。

今天主要学习了最短路,战绩马马虎虎,题目都不算太难。

  • AC:4道
  • WA:1道【P1342 请柬】,后面有时间继续研究

题目

  • D - joisino's travel
    • https://atcoder.jp/contests/abc073/tasks/abc073_d

Atcoder国家有N个城镇,由M条双向可移动的道路连接而成。

另外,第i条路是町

A_i

和城镇

B_i

之间的距离用

C_i

连接。

姐姐要去这个国家的R个城市

r_1,r_2..r_R

她将飞往她访问的第一个城镇,然后从她访问的最后一个城镇飞回来,但在接下来的行程中,她将不得不通过公路旅行。

请回答访问城市的顺序,决定道路的移动距离最小时的移动距离。

制約
2≦N≦200
1≦M≦N×(N-1)/2
2≦R≦min(8,N)
r_i≠r_j (i≠j)
1≦A_i,B_i≦N , A_i≠B_i
(A_i,B_i)≠(A_j,B_j),(A_i,B_i)≠(B_j,A_j) (i≠j)
1≦C_i≦100000
  • 所有城镇之间只能靠道路移动。
  • 输入全部为整数。

入力
  • N M R
  • r
_1

...... r

_R
  • A
_1

B

_1

C

_1
  • :
  • A
_M

B

_M

C

_M
出力

将访问城市的顺序输出为道路上的移动距离最小的距离。


入力例 1
代码语言:javascript
复制
3 3 3
1 2 3
1 2 1
2 3 1
3 1 4
出力例 1
代码语言:javascript
复制
2

例如,按照町1、町2、町3的顺序访问的话,移动距离为2,最小。


入力例 2
代码语言:javascript
复制
3 3 2
1 3
2 3 2
1 3 6
1 2 2
出力例 2
代码语言:javascript
复制
4

无论是访问了町1之后访问町3,还是访问了町3之后访问町1,町1和町3之间的最短距离都是4,所以无论选择哪个顺序,答案都是4。


入力例 3
代码语言:javascript
复制
4 6 3
2 3 4
1 2 4
2 3 3
4 3 1
1 4 1
4 2 2
3 1 6
出力例 3
代码语言:javascript
复制
3

小码匠

思路
  • 首先跑floyd计算最短距离;
  • 然后跑全排列确定城市顺序。
代码
代码语言:javascript
复制
#include <bits/stdc++.h>
using namespace std;
#define endl '\n';
 
void best_coder() {
    int n, m, r;
    cin >> n >> m >> r;
    vector<vector<int>> g(n, vector<int>(n, 1e9));
    vector<int> l(r);
    for (int i = 0; i < r; ++i) {
        cin >> l[i];
        --l[i];
    }
    sort(l.begin(), l.end());
    for (int i = 0; i < m; ++i) { //存储边的情况
        int u, v, w;
        cin >> u >> v >> w;
        --u;
        --v;
        g[u][v] = w;
        g[v][u] = w;
    }
    for (int i = 0; i < n; ++i) {
        g[i][i] = 0;
    }
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            if (j == i) {
                continue;
            }
            for (int s = 0; s < n; ++s) {
                if (s == i || s == j) {
                    continue;
                }
                g[j][s] = min(g[j][s], g[i][s] + g[j][i]);
            }
        }
    }
    int ans = 1e9;
    do {
        int cnt = 0;
        for (int i = 0; i < r - 1; ++i) {
            cnt += g[l[i]][l[i + 1]];
        }
        ans = min(cnt, ans);
    } while (next_permutation(l.begin(), l.end()));
    cout << ans;
}
 
void happy_coder() {
}
 
int main() {
    // 提升cin、cout效率
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
 
    // 小码匠
    best_coder();
 
    // 最优解
    // happy_coder();
 
    // 返回
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-01-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小码匠和老码农 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 10分钟而已
  • 题目
    • 制約
      • 入力
        • 出力
          • 入力例 1
            • 出力例 1
              • 入力例 2
                • 出力例 2
                  • 入力例 3
                    • 出力例 3
                    • 小码匠
                      • 思路
                        • 代码
                        领券
                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档