嘟嘟嘟

题意概括一下,就是在无向图上求一条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 个电话线免费的这个状态是否出队过。

具体看代码吧,挺好懂。

 #include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a) memset(a, 0, sizeof(a))
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-;
const int maxn = 1e3 + ;
inline ll read()
{
ll ans = ;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) {last = ch; ch = getchar();}
while(isdigit(ch)) {ans = ans * + ch - ''; ch = getchar();}
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < ) x = -x, putchar('-');
if(x >= ) write(x / );
putchar(x % + '');
} int n, p, k;
vector<int> v[maxn], c[maxn]; struct Node
{
int _dp, nod, p;
bool operator < (const Node& other)const
{
return _dp > other._dp;
}
};
int dp[maxn][maxn];
bool in[maxn][maxn]; void dijkstra(int s)
{
for(int i = ; i <= n; ++i)
for(int j = ; j <= n; ++j) dp[i][j] = INF;
dp[s][] = ;
priority_queue<Node> q;
q.push((Node){dp[s][], s, });
while(!q.empty())
{
int now = q.top().nod, p = q.top().p; q.pop();
if(in[now][p]) continue;
in[now][p] = ;
for(int i = ; i < (int)v[now].size(); ++i)
{
int to = v[now][i];
if(dp[to][p] > max(dp[now][p], c[now][i]))
{
dp[to][p] = max(dp[now][p], c[now][i]);
q.push((Node){dp[to][p], to, p});
}
if(p < k && dp[to][p + ] > dp[now][p])
{
dp[to][p + ] = dp[now][p];
q.push((Node){dp[to][p + ], to, p + });
}
}
}
write(dp[n][k] == INF ? - : dp[n][k]); enter;
} int main()
{
n = read(); p = read(); k = read();
for(int i = ; i <= p; ++i)
{
int x = read(), y = read(), co = read();
v[x].push_back(y); c[x].push_back(co);
v[y].push_back(x); c[y].push_back(co);
}
dijkstra();
return ;
}

[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. 以面向对象的思想实现数据表的添加和查询,JDBC代码超详细

    以面向对象的思想编写JDBC程序,实现使用java程序向数据表中添加学生信息,并且可以实现给定身份证号查询学生信息或给定准考证号查询学生信息. 创建的数据表如下: CREATE TABLE EXAMS ...

  2. [LeetCode]Remove Duplicates from Sorted Array题解

    Remove Duplicates from Sorted Array: Given a sorted array, remove the duplicates in place such that ...

  3. CSS实现文字两端对齐

    最近的项目遇到了这样的需求:(要求标题部分不管文字多少,都必须两端对齐) 如下图: 当时也没有多想直接使用‘ ’进行代替,毕竟产品同学想快一点看到效果,不敢怠慢!不过到第二个页面就傻眼了. 如图: 这 ...

  4. java停止一个线程

    Thread类中有start(), stop()方法,不过stop方法已经被废弃掉. 平时其实也有用过,共享一个变量,相当于标志,不断检查标志,判断是否退出线程 如果有阻塞,需要使用Thread的in ...

  5. PHP 如何向关联数组指定的 Key 之前插入元素

    PHP 关联数组可以通过三种方式插入新元素: $array[$insert_key] = $insert_value; $array = array_merge($array, $insert_arr ...

  6. 什么是首字节时间(TTFB)

    第一字节响应时间(TTFB)=从发送请求到WEB服务器的时间+WEB服务器处理请求并生成响应花费的时间+WEB服务器生成响应到浏览器花费的时间测量第一字节响应时间(TTFB)的工具:http://ww ...

  7. UTF-8和GBK编码转换iconv

    iconv("GBK", "UTF-8", $str);//将GBK编码转换成UTF8编码

  8. laravel开发之-安装laravel-admin

    1.输入命令:composer require encore/laravel-admin "1.4.*" 2.在config/app.php中添加 :Encore\Admin\Pr ...

  9. Oql实体转自定义对象

    返回单体: GroupEnvironmentDTO 是自定义的一个DTO, GroupEnvironmentEntity.MapToPOCO(dto);  把上述查出来的对象转换为DTO 返回实体集合 ...

  10. WinSxS文件夹瘦身

    WinSxS文件夹瘦身 2014-5-8 18:03:32来源:IT之家作者:阿象责编:阿象 评论:27 刚刚,我们分享了如何用DISM管理工具查看Win8.1 WinSxS文件夹实际大小.对于Win ...