当前位置:   article > 正文

L2-036 网红点打卡攻略 (25 分) Java题解 (图,模拟)

l2-036 网红点打卡攻略

输入样例:

  1. 6 13
  2. 0 5 2
  3. 6 2 2
  4. 6 0 1
  5. 3 4 2
  6. 1 5 2
  7. 2 5 1
  8. 3 1 1
  9. 4 1 2
  10. 1 6 1
  11. 6 3 2
  12. 1 2 1
  13. 4 5 3
  14. 2 0 2
  15. 7
  16. 6 5 1 4 3 6 2
  17. 6 5 2 1 6 3 4
  18. 8 6 2 1 6 3 4 5 2
  19. 3 2 1 5
  20. 6 6 1 3 4 5 2
  21. 7 6 2 1 3 4 5 2
  22. 6 5 2 1 4 3 6

输出样例:

  1. 3
  2. 5 11

样例说明:

第 2、3、4、6 条都不满足攻略的基本要求,即不能做到从家里出发,在每个网红点打卡仅一次,且能回到家里。所以满足条件的攻略有 3 条。

第 1 条攻略的总路费是:(0->5) 2 + (5->1) 2 + (1->4) 2 + (4->3) 2 + (3->6) 2 + (6->2) 2 + (2->0) 2 = 14;

第 5 条攻略的总路费同理可算得:1 + 1 + 1 + 2 + 3 + 1 + 2 = 11,是一条更省钱的攻略;

第 7 条攻略的总路费同理可算得:2 + 1 + 1 + 2 + 2 + 2 + 1 = 11,与第 5 条花费相同,但序号较大,所以不输出。


解题思路:

题意大致是给出若干个序列,判断合法序列数,合法条件为序列中的点在图中正好都只出现过一次,并且相邻两点都有通路。从0号点开始,遍历完景点,再回到0号点,输出合法条数和最小权值即可。

Java代码:

  1. import java.io.*;
  2. import java.util.Arrays;
  3. public class Main {
  4. public static void main(String[] args) throws IOException {
  5. BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  6. String[] split = br.readLine().split(" ");
  7. int n = Integer.parseInt(split[0]);
  8. int m = Integer.parseInt(split[1]);
  9. final int INF = 0x3f3f3f3f;
  10. int [][]g = new int[n + 1][n + 1];
  11. boolean []vis = new boolean[n + 1]; // 标志是否访问过该点
  12. for(int i = 0; i <= n; i++) Arrays.fill(g[i], INF);
  13. while(m-- > 0) {
  14. split = br.readLine().split(" ");
  15. int a = Integer.parseInt(split[0]);
  16. int b = Integer.parseInt(split[1]);
  17. int w = Integer.parseInt(split[2]);
  18. g[a][b] = g[b][a] = w;
  19. }
  20. int k = Integer.parseInt(br.readLine());
  21. int idx = -1, ans = Integer.MAX_VALUE, count = 0;
  22. for(int j = 1; j <= k; j++) {
  23. int cnt = n; // 记录共访问了几个点
  24. vis = new boolean[n + 1];
  25. split = br.readLine().split(" ");
  26. m = Integer.parseInt(split[0]);
  27. int []arr = new int[m];
  28. for(int i = 0; i < m; i++)
  29. arr[i] = Integer.parseInt(split[i + 1]);
  30. int sum = 0; // 从家到第一个点
  31. if(g[0][arr[0]] != INF) sum += g[0][arr[0]];
  32. else continue;
  33. int i = 0;
  34. for(i = 0; i < m - 1; i++) // 遍历所有景点
  35. if(g[arr[i]][arr[i + 1]] != INF && !vis[arr[i]]) {
  36. sum += g[arr[i]][arr[i + 1]];
  37. vis[arr[i]] = true;
  38. cnt--;
  39. }else break;
  40. if(i != m - 1) continue;
  41. if(g[arr[m - 1]][0] != INF && !vis[arr[m - 1]]) { // 从最后一个景点回到家
  42. sum += g[arr[m - 1]][0];
  43. vis[arr[m - 1]] = true;
  44. cnt--;
  45. }else continue;
  46. if(cnt != 0) continue; // 如果访问的不是正好n个点,则不符合题意
  47. count++; // 满足要求的方案数
  48. if(ans > sum) {
  49. ans = sum;
  50. idx = j;
  51. }
  52. }
  53. System.out.println(count);
  54. System.out.println(idx + " " + ans);
  55. }
  56. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/940327
推荐阅读
相关标签
  

闽ICP备14008679号