1.USACO08JAN  Telephone Lines 题面

由于问的是最大值最小,所以二分加验证就好了

比较显然的,题干问的是第k+1长的路最短;

那么二分答案是正确的方向;

但是怎么验证?

我们可以将所有边权大于二分的答案的边视为边权是1,否则看成0;

然后从1~n跑最短路,如果答案大于二分的答案那么就不成立,否则成立;

这种思维比较重要,代码还是很简单的;

#include <bits/stdc++.h>
using namespace std;
int head[2000010],cnt;
class littlestar{
public:
int to;
int nxt;
int w;
void add(int u,int v,int gg){
nxt=head[u];
to=v;
w=gg;
head[u]=cnt;
}
}star[2000010];
int n,p,k;
int dis[100010],vis[100010];
bool SPFA(int x)
{
queue<int> q;
memset(dis,0x3f,sizeof(dis));
dis[1]=0;
memset(vis,0,sizeof(vis));
q.push(1);
while(q.size()){
int u=q.front();
q.pop();
vis[u]=0;
for(int i=head[u];i;i=star[i].nxt){
int v=star[i].to;
if(dis[v]>dis[u]+(star[i].w>x)){
dis[v]=dis[u]+(star[i].w>x);
if(!vis[v]){
vis[v]=1;
q.push(v);
}
}
}
}
if(dis[n]<=k) return 1;
else{
return 0;
}
}
int main()
{
cin>>n>>p>>k;
for(int i=1;i<=p;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
star[++cnt].add(u,v,w);
star[++cnt].add(v,u,w);
}
int l=0,r=1000000;
while(l<r){
int mid=(l+r)/2;
if(SPFA(mid)){
r=mid;
}
else{
l=mid+1;
}
}
if(l==1000000) l=-1;
cout<<l<<endl;
}

2.[JLOI2011]飞行路线题面

这道题很上一道题不太一样,所求的是对于每种方案去掉前k大边后的最短路;

首先由于k很小,可以进行分层图;

第i层图表示目前已经删去了i条边的最短路;

对于点对(i,j)在任意层中边权是w;从第i层到第i+1层的边权是0;

然后堆优化+dijkstra就可以了;

#include <bits/stdc++.h>
using namespace std;
int head[5000010],cnt;
class littlestar{
public:
int to;
int nxt;
int w;
void add(int u,int v,int gg){
nxt=head[u];
to=v;
w=gg;
head[u]=cnt;
}
}star[5000010];
int n,p,k;
int dis[5000010],vis[5000010];
int S,T;
void dijkstra()
{
memset(dis,0x3f,sizeof(dis));
priority_queue<pair<int,int> > q;
q.push(make_pair(0,S));
dis[S]=0;
while(q.size()){
int u=q.top().second;
q.pop();
if(vis[u]) continue;
vis[u]=1;
for(int i=head[u];i;i=star[i].nxt){
int v=star[i].to;
if(dis[v]>dis[u]+star[i].w){
dis[v]=dis[u]+star[i].w;
q.push(make_pair(-dis[v],v));
}
}
}
}
int main()
{
cin>>n>>p>>k;
cin>>S>>T;
++S;++T;
for(int i=1;i<=p;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
++u; ++v;
star[++cnt].add(u,v,w);
star[++cnt].add(v,u,w);
for(int j=0;j<k;j++){
star[++cnt].add((j+1)*n+u,(j+1)*n+v,w);
star[++cnt].add((j+1)*n+v,(j+1)*n+u,w);
star[++cnt].add(j*n+u,(j+1)*n+v,0);
star[++cnt].add(j*n+v,(j+1)*n+u,0);
}
}
for(int j=0;j<=k;j++){
star[++cnt].add(j*n+T,n*30+T,0);
}
dijkstra();
cout<<dis[n*30+T];
}

3.[BJWC2012]冻结

和上一道题思路一样,都是分层图,但连接第i层和第i+1层的边权不再是0,而是w/2;

#include <bits/stdc++.h>
using namespace std;
int head[5000010],cnt;
class littlestar{
public:
int to;
int nxt;
int w;
void add(int u,int v,int gg){
nxt=head[u];
to=v;
w=gg;
head[u]=cnt;
}
}star[5000010];
int n,p,k;
int dis[5000010],vis[5000010];
void dijkstra()
{
memset(dis,0x3f,sizeof(dis));
priority_queue<pair<int,int> > q;
q.push(make_pair(0,1));
dis[1]=0;
while(q.size()){
int u=q.top().second;
q.pop();
if(vis[u]) continue;
vis[u]=1;
for(int i=head[u];i;i=star[i].nxt){
int v=star[i].to;
if(dis[v]>dis[u]+star[i].w){
dis[v]=dis[u]+star[i].w;
q.push(make_pair(-dis[v],v));
}
}
}
}
int main()
{
cin>>n>>p>>k;
for(int i=1;i<=p;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
star[++cnt].add(u,v,w);
star[++cnt].add(v,u,w);
for(int j=0;j<k;j++){
star[++cnt].add((j+1)*n+u,(j+1)*n+v,w);
star[++cnt].add((j+1)*n+v,(j+1)*n+u,w);
star[++cnt].add(j*n+u,(j+1)*n+v,w/2);
star[++cnt].add(j*n+v,(j+1)*n+u,w/2);
}
}
for(int j=0;j<=k;j++){
star[++cnt].add(j*n+n,n*30+1,0);
}
dijkstra();
cout<<dis[n*30+1];
}

4.[USACO09FEB]改造路Revamping Trails

思路重复,代码几乎一样,就不多说了;把这到题放到这里的原因是想告诉大家,USACO的题要好好做啊,很多省选题都来源于此;

#include <bits/stdc++.h>
using namespace std;
int head[5000010],cnt;
class littlestar{
public:
int to;
int nxt;
int w;
void add(int u,int v,int gg){
nxt=head[u];
to=v;
w=gg;
head[u]=cnt;
}
}star[5000010];
int n,p,k;
int dis[5000010],vis[5000010];
void dijkstra()
{
memset(dis,0x3f,sizeof(dis));
priority_queue<pair<int,int> > q;
q.push(make_pair(0,1));
dis[1]=0;
while(q.size()){
int u=q.top().second;
q.pop();
if(vis[u]) continue;
vis[u]=1;
for(int i=head[u];i;i=star[i].nxt){
int v=star[i].to;
if(dis[v]>dis[u]+star[i].w){
dis[v]=dis[u]+star[i].w;
q.push(make_pair(-dis[v],v));
}
}
}
}
int main()
{
cin>>n>>p>>k;
for(int i=1;i<=p;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
star[++cnt].add(u,v,w);
star[++cnt].add(v,u,w);
for(int j=0;j<k;j++){
star[++cnt].add((j+1)*n+u,(j+1)*n+v,w);
star[++cnt].add((j+1)*n+v,(j+1)*n+u,w);
star[++cnt].add(j*n+u,(j+1)*n+v,0);
star[++cnt].add(j*n+v,(j+1)*n+u,0);
}
}
for(int j=0;j<=k;j++){
star[++cnt].add(j*n+n,n*30+1,0);
}
dijkstra();
cout<<dis[n*30+1];
}

有关最短路上的第k小/大值的总结的更多相关文章

  1. luogu P3834 【模板】可持久化线段树 1(主席树) 查询区间 [l, r] 内的第 k 小/大值

    ————————————————版权声明:本文为CSDN博主「ModestCoder_」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明.原文链接:https:// ...

  2. poj2828(线段树查找序列第k小的值)

    题目链接:https://vjudge.net/problem/POJ-2828 题意:有n个人,依次给出这n个人进入队列时前面有多少人p[i],和它的权值v[i],求最终队列的权值序列. 思路:基本 ...

  3. MATLAB寻找数组前k个大值

    有时候我们需要寻找数组的前k个大值并按照顺序输出, 在C语言可以通过快速排序等算法,快速求得,这里用matlab写了一个比较简单实用的程序(适用于数组长度不是特别大的情况). function [va ...

  4. 求第 k 小:大元素

    #include<bits/stdc++.h> using namespace std; void swap_t(int a[],int i,int j) { int t=a[i]; a[ ...

  5. poj 3685 矩阵问题 查找第K小的值

    题意:N阶矩阵Aij= i2 + 100000 × i + j2 – 100000 × j + i × j,求第M小的元素. 思路:双重二分 考虑到,aij是跟着i递增的,所以i可以作为一个二分搜索 ...

  6. 算法---数组总结篇2——找丢失的数,找最大最小,前k大,第k小的数

    一.如何找出数组中丢失的数 题目描述:给定一个由n-1个整数组成的未排序的数组序列,其原始都是1到n中的不同的整数,请写出一个寻找数组序列中缺失整数的线性时间算法 方法1:累加求和 时间复杂度是O(N ...

  7. 树上第k小,可持久化线段树+倍增lca

    给定一颗树,树的每个结点都有权值, 有q个询问,每个询问是 u v k ,表示u到v路径上第k小的权值是多少. 每个结点所表示的线段树,是父亲结点的线段树添加该结点的权值之后形成的新的线段树 c[ro ...

  8. BZOJ 3065 带插入区间K小值(sag套线段树)

    3065: 带插入区间K小值 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 4696  Solved: 1527[Submit][Status][Di ...

  9. 刷题-力扣-230. 二叉搜索树中第K小的元素

    230. 二叉搜索树中第K小的元素 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/kth-smallest-element-in-a ...

随机推荐

  1. jQuery文档操作之删除操作

    remove() 语法: $(selector).remove(); 解释:删除节点后,事件也会删除(简言之,删除了整个标签) $("ul").remove(); detach() ...

  2. 关于lower_bound()和upper_bound()

    关于lower_bound()和upper_bound(): 参考:关于lower_bound( )和upper_bound( )的常见用法 注意:查找的数组必须要是排好序的.因为,它们查找的方式也是 ...

  3. python-pandas-1

    series Series 是pandas两大数据结构中(DataFrame,Series)的一种. 创建Series Series的定义:Series是一种类似于一维数组的对象,它由一组数据(各种N ...

  4. 网络爬虫技术实现java依赖库整理输出

    网络爬虫技术实现java依赖库整理输出 目录 1       简介... 2 1.1      背景介绍... 2 1.2      现有方法优缺点对比... 2 2       实现方法... 2 ...

  5. jmeter参数化之 CSV data set config

    第一步:测试计划右键--创建线程组   第二步:选择线程组:右键--sample---创建:http request 配置协议类型和服务名称,method 和path 第三步:选择线程组下的http ...

  6. beta week 2/2 Scrum立会报告+燃尽图 07

    此作业要求参见https://edu.cnblogs.com/campus/nenu/2019fall/homework/9959 一.小组情况 组长:贺敬文组员:彭思雨 王志文 位军营 徐丽君队名: ...

  7. Java-内存模型(JSR-133)

    Java 内存模型(Java Memory Model,JMM)看上去和 Java 内存结构(JVM 运行时内存结构)差不多,但这两者并不是一回事.JMM 并不像 JVM 内存结构一样是真实存在的,它 ...

  8. 浅析java中的四种线程池

      1.使用线程池的好处 2.JUC中几种常用的线程池 java.util.concurrent包下的Executors工厂类,提供了一系列的线程池的创建方法,其构造方法如下: public Thre ...

  9. 前端使用pdf.js预览pdf文件,超级简单

    现在的浏览器基本都支持直接把pdf文件拖到浏览器就可以打开了,不用安装额外的插件.但是不同的浏览器显示的页面不一样.如果我们想在网页上统一预览pdf怎样实现呢? Mozilla开源了一个插件pdf.j ...

  10. git远程删除分支后,本地执行git branch -a依然能看到删除分支到底该咋整?

    使用命令git branch -a可以查看所有本地分支和远程分支(git branch -r 可以只查看远程分支) 如果发现很多在远程仓库已经删除的分支在本地依然可以看到到底该怎么办呢?(反正强迫症受 ...