嘟嘟嘟

题意概括一下,就是在无向图上求一条1到n的路径,使路径上第k + 1大的边权尽量小。

考虑dp,令dp[i][j] 表示走到节点 i,路线上有 j 条电话线免费时,路径上最贵的电缆花费最小是多少。则对于一条从u到v,长度为w的边,转移方程是:

    1.这条电缆要付费:dp[v][p] = min(dp[v][p], max(dp[u][p], w))

    2.这条电缆免费:dp[v][p + 1] = min(dp[v][p +1], dp[u][p])

不过这是在图上dp,转移不能保证无后效性,因此我们可以利用spfa或dijkstra使dp有一个合理的顺序,因为最短路算法跑出来的是一个DAG,而dp状态之间的转移实质上就是在一个DAG上转移。

因为spfa他死了,所以我就用dijkstra写:考虑当前的“最短路”,不是单纯的dis,而是当前最优的dp[i][j],因此我们要开一个结构体优先队列,里面有dp[i][j], i 和 j。然后按dp[i][j]排序。

另外朴素的dijkstra是如果节点u出队了就不在入队,然而这道题需要开两维,in[i][j]表示节点 i ,j 个电话线免费的这个状态是否出队过。

具体看代码吧,挺好懂。

  1. #include<cstdio>
  2. #include<iostream>
  3. #include<cmath>
  4. #include<algorithm>
  5. #include<cstring>
  6. #include<cstdlib>
  7. #include<cctype>
  8. #include<vector>
  9. #include<stack>
  10. #include<queue>
  11. using namespace std;
  12. #define enter puts("")
  13. #define space putchar(' ')
  14. #define Mem(a) memset(a, 0, sizeof(a))
  15. typedef long long ll;
  16. typedef double db;
  17. const int INF = 0x3f3f3f3f;
  18. const db eps = 1e-;
  19. const int maxn = 1e3 + ;
  20. inline ll read()
  21. {
  22. ll ans = ;
  23. char ch = getchar(), last = ' ';
  24. while(!isdigit(ch)) {last = ch; ch = getchar();}
  25. while(isdigit(ch)) {ans = ans * + ch - ''; ch = getchar();}
  26. if(last == '-') ans = -ans;
  27. return ans;
  28. }
  29. inline void write(ll x)
  30. {
  31. if(x < ) x = -x, putchar('-');
  32. if(x >= ) write(x / );
  33. putchar(x % + '');
  34. }
  35.  
  36. int n, p, k;
  37. vector<int> v[maxn], c[maxn];
  38.  
  39. struct Node
  40. {
  41. int _dp, nod, p;
  42. bool operator < (const Node& other)const
  43. {
  44. return _dp > other._dp;
  45. }
  46. };
  47. int dp[maxn][maxn];
  48. bool in[maxn][maxn];
  49.  
  50. void dijkstra(int s)
  51. {
  52. for(int i = ; i <= n; ++i)
  53. for(int j = ; j <= n; ++j) dp[i][j] = INF;
  54. dp[s][] = ;
  55. priority_queue<Node> q;
  56. q.push((Node){dp[s][], s, });
  57. while(!q.empty())
  58. {
  59. int now = q.top().nod, p = q.top().p; q.pop();
  60. if(in[now][p]) continue;
  61. in[now][p] = ;
  62. for(int i = ; i < (int)v[now].size(); ++i)
  63. {
  64. int to = v[now][i];
  65. if(dp[to][p] > max(dp[now][p], c[now][i]))
  66. {
  67. dp[to][p] = max(dp[now][p], c[now][i]);
  68. q.push((Node){dp[to][p], to, p});
  69. }
  70. if(p < k && dp[to][p + ] > dp[now][p])
  71. {
  72. dp[to][p + ] = dp[now][p];
  73. q.push((Node){dp[to][p + ], to, p + });
  74. }
  75. }
  76. }
  77. write(dp[n][k] == INF ? - : dp[n][k]); enter;
  78. }
  79.  
  80. int main()
  81. {
  82. n = read(); p = read(); k = read();
  83. for(int i = ; i <= p; ++i)
  84. {
  85. int x = read(), y = read(), co = read();
  86. v[x].push_back(y); c[x].push_back(co);
  87. v[y].push_back(x); c[y].push_back(co);
  88. }
  89. dijkstra();
  90. return ;
  91. }

[USACO08JAN]Telephone Lines的更多相关文章

  1. Luogu P1948 [USACO08JAN]Telephone Lines

    题目 两眼题 二分一个\(lim\),然后跑最短路(边权\(\le lim\)的边长度为\(0\),\(>lim\)的长度为\(1\)),然后判断\(dis_{1,n}\le k\). #inc ...

  2. P1948 [USACO08JAN]Telephone Lines S

    题意描述 在无向图中求一条从 \(1\) 到 \(N\) 的路径,使得路径上第 \(K+1\) 大的边权最小. 等等,最大的最小...如此熟悉的字眼,难道是 二分答案. 下面进入正题. 算法分析 没错 ...

  3. POJ3662 [USACO08JAN]Telephone Lines (二分答案/分层图求最短路)

    这道题目有两种解法: 1.将每个点视为一个二元组(x,p),表示从起点到x有p条路径免费,相当于构建了一张分层图,N*k个节点,P*k条边.在这张图上用优先队列优化的SPFA算法求解,注意这里的d数组 ...

  4. 洛谷 P1948 [USACO08JAN]电话线Telephone Lines

    P1948 [USACO08JAN]电话线Telephone Lines 题目描述 Farmer John wants to set up a telephone line at his farm. ...

  5. 洛谷 P1948 [USACO08JAN]电话线Telephone Lines 题解

    P1948 [USACO08JAN]电话线Telephone Lines 题目描述 Farmer John wants to set up a telephone line at his farm. ...

  6. Luogu P1948 [USACO08JAN]电话线Telephone Lines(最短路+dp)

    P1948 [USACO08JAN]电话线Telephone Lines 题意 题目描述 Farmer John wants to set up a telephone line at his far ...

  7. 洛谷 P1948 [USACO08JAN]电话线Telephone Lines 最短路+二分答案

    目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例 输出样例 说明 思路 AC代码 题面 题目链接 P1948 [USACO08JAN]电话线Telephone ...

  8. USACO Telephone Lines

    洛谷 P1948 [USACO08JAN]电话线Telephone Lines https://www.luogu.org/problem/P1948 JDOJ 2556: USACO 2008 Ja ...

  9. BZOJ1614: [Usaco2007 Jan]Telephone Lines架设电话线

    1614: [Usaco2007 Jan]Telephone Lines架设电话线 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 892  Solved: ...

随机推荐

  1. “PPT中如何插入和提取swf文件”的解决方案

    解决方案: 如何在PPT中插入swf文件: 1.依次单击Office按钮,Powerpoint选项,勾选“在功能区显示‘开发工具’选项卡”后,确定: 2.单击“开发工具”选项卡中的“其他控件”按钮,然 ...

  2. 三:Bootstrap-js插件

    模式框: <button class="btn btn-default btn-lg" data-toggle="modal" data-target=& ...

  3. kinect 深度图像去噪算法

    算法设计思路 (1)读取16位深度图像到待处理图像帧组: (2)ROI区域计算 由于kinect 彩色摄像头和红外深度摄像头是存在视角偏差的,经过视角对齐后,得到的深度图像是有黑边的.此处通过取帧组第 ...

  4. Win10环境下Redis和Redis desktop manager 安装

    1.Redis的下载地址: https://github.com/MicrosoftArchive/redis/releases/download/win-3.2.100/Redis-x64-3.2. ...

  5. ActiveMQ的用途

    ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线. ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现. 消息队列的主要作用是为了 ...

  6. canvas toDataURL() 方法如何生成部分画布内容的图片

    HTMLCanvasElement.toDataURL() 方法返回一个包含图片展示的 data URI .可以使用 type参数其类型,默认为 PNG 格式.图片的分辨率为96dpi. 如果画布的高 ...

  7. Leetcode算法比赛----Longest Absolute File Path

    问题描述 Suppose we abstract our file system by a string in the following manner: The string "dir\n ...

  8. C++学习笔记(4)----模板实参推断

    1. 如图所示代码,模板函数 compare(const T&, const T&) 要求两个参数类型要一样. compare("bye","dad&qu ...

  9. 解决linux下fflush(stdin)无效

    void clean_stdin(void) { int c; do { c = getchar(); } while (c != '\n' && c != EOF); }

  10. 同步(Synchronous)和异步(Asynchronous)的概念

    web项目中的同步与异步 在我们平时的web项目开发中会经常听到ajax请求这样一个称呼,在web项目中可以通过js或者jquery发送同步请求又或者异步请求,同步请求呢往往代表着你必须等待这次请求结 ...