[USACO08JAN]Telephone Lines
题意概括一下,就是在无向图上求一条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的更多相关文章
- Luogu P1948 [USACO08JAN]Telephone Lines
题目 两眼题 二分一个\(lim\),然后跑最短路(边权\(\le lim\)的边长度为\(0\),\(>lim\)的长度为\(1\)),然后判断\(dis_{1,n}\le k\). #inc ...
- P1948 [USACO08JAN]Telephone Lines S
题意描述 在无向图中求一条从 \(1\) 到 \(N\) 的路径,使得路径上第 \(K+1\) 大的边权最小. 等等,最大的最小...如此熟悉的字眼,难道是 二分答案. 下面进入正题. 算法分析 没错 ...
- POJ3662 [USACO08JAN]Telephone Lines (二分答案/分层图求最短路)
这道题目有两种解法: 1.将每个点视为一个二元组(x,p),表示从起点到x有p条路径免费,相当于构建了一张分层图,N*k个节点,P*k条边.在这张图上用优先队列优化的SPFA算法求解,注意这里的d数组 ...
- 洛谷 P1948 [USACO08JAN]电话线Telephone Lines
P1948 [USACO08JAN]电话线Telephone Lines 题目描述 Farmer John wants to set up a telephone line at his farm. ...
- 洛谷 P1948 [USACO08JAN]电话线Telephone Lines 题解
P1948 [USACO08JAN]电话线Telephone Lines 题目描述 Farmer John wants to set up a telephone line at his farm. ...
- Luogu P1948 [USACO08JAN]电话线Telephone Lines(最短路+dp)
P1948 [USACO08JAN]电话线Telephone Lines 题意 题目描述 Farmer John wants to set up a telephone line at his far ...
- 洛谷 P1948 [USACO08JAN]电话线Telephone Lines 最短路+二分答案
目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例 输出样例 说明 思路 AC代码 题面 题目链接 P1948 [USACO08JAN]电话线Telephone ...
- USACO Telephone Lines
洛谷 P1948 [USACO08JAN]电话线Telephone Lines https://www.luogu.org/problem/P1948 JDOJ 2556: USACO 2008 Ja ...
- BZOJ1614: [Usaco2007 Jan]Telephone Lines架设电话线
1614: [Usaco2007 Jan]Telephone Lines架设电话线 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 892 Solved: ...
随机推荐
- 使用IndexOf方法来判断“咳嗽”出现的次数及索引、使用Dictionary<key,value> 集合统计没个字符出现的次数
static void Main(string[] args) { #region string str = "患者:医生我咳嗽的很严重,大夫:你多大年纪了? 患者:我75岁 大夫:那二十岁 ...
- linux中find与rm实现查找并删除文件
find命令: find . -name '*.log' #查找当前目录下的log文件 查找并删除: find . -name '*.log' -type f -print -exec rm -rf ...
- ASP.NET 表单验证方法与客户端(浏览器)服务器交互机制的故事
想到这个问题完全是一个意外吧,是在寻找另外一个问题答案的过程中,才对验证方法与浏览器服务器交互机制的关系有了清晰的认识. 先说下验证方法,验证方法分为前台验证和后台验证. 前台验证就是类似jQuery ...
- pollard_rho 算法进行质因数分解
//************************************************ //pollard_rho 算法进行质因数分解 //*********************** ...
- 快速幂取模(POJ 1995)
http://poj.org/problem?id=1995 以这道题来分析一下快速幂取模 a^b%c(这就是著名的RSA公钥的加密方法),当a,b很大时,直接求解这个问题不太可能 利用公式a*b%c ...
- MVC 导出Execl 的总结几种方式 (一)
在ASP.NET 中导出Execl 表格有很多方式,有利有弊,就是看自己怎么使用了:下面就是自己总结了几种导出Execl 方式的,仅供参考. 导出Execl 的原理都是一样的,其实都是将数据整合成ta ...
- HTML5拖拽/拖放(drag & drop)详解
H5中拖拽属性: draggable: auto | true | false 拖动事件: - dragstart 在元素开始被拖动时触发 - dragend 在拖动操作完成时触发 - dra ...
- input textarea监听鼠标粘贴
发现一个问题,在input/textarea中如果是鼠标粘贴内容进去,发现判断不了value的改变,html代码如下: <!doctype html> <html> <h ...
- Linux 安装命令
- Linux命令行bash批量重命名文件
本文介绍下,在linux下使用shell批量重命名文件的例子,有需要的朋友参考下吧. 在linux中,重命名文件名,需要用到mv命令.如果需要批量重命名名一批文件,就需要写bash脚本或命令行了. 例 ...