【bzo1579】拆点+dijkstra优先队列优化+其他优化
题意:
n个点,m条边,问从1走到n的最短路,其中有K次机会可以让一条路的权值变成0。
1≤N≤10000;1≤M≤500000;1≤K≤20
题解:
拆点,一个点拆成K个,分别表示到了这个点时还有多少次机会。
(x,k)-->(y,k-1),cost=0 或 (x,k)-->(y,k),cost=a[i].d;
这题数据比较大, 需要很多优化。(应该只是蒟蒻我才需要这么多优化。。)
1.不用spfa(时间复杂度不稳定),用dijkstra+优先队列优化
2.拆点不拆边。g[i]表示i这个点是由谁拆分出来的,id[i]表示i这个点表示还能用几次,st[i]表示i拆分出来的点的编号从什么开始,图就按照原图建立,比如(x,k)-->(y,k-1)就可以直接找到st[x]+k -- > st[y]+k-1。
3.如果“目标点n 用完了K次机会”这个状态到1的最短路已经算出来了,那一定是最优的,其它的都不用算了。加了这句话从10s+跑到了0.6s。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<cmath>
using namespace std; typedef long long LL;
const int N=**,M=;//不知道为什么点要开两倍才能过。。。
const LL INF=(LL)1e15;
struct node{
int x,y,next;
LL d;
}a[*M];
int n,m,K,len,num,first[N],g[N],id[N],st[N];
LL dis[N],mn[N];
struct point{int x;LL d;};
struct cmp{
bool operator () (point &x,point &y){return x.d>y.d;}
};
priority_queue<point,vector<point>,cmp> q; LL minn(LL x,LL y){return x<y ? x:y;} void ins(int x,int y,LL d)
{
a[++len].x=x;a[len].y=y;a[len].d=d;
a[len].next=first[x];first[x]=len;
} void dijkstra()
{
int y,bk=;
point t;
for(int i=;i<=num;i++) dis[i]=-;
// for(int i=1;i<=num;i++) if(dis[i]!=-1) printf("%d g = %d id = %d dis = %lld\n",i,g[i],id[i],dis[i]); memset(mn,,sizeof(mn));
while(!q.empty()) q.pop();
for(int i=;i<=K;i++) dis[st[]+i]=; for(int i=first[];i;i=a[i].next)
{
for(int j=;j<=K;j++)
{
t.x=st[a[i].y]+j;
t.d=dis[st[]+j]+a[i].d;
if(mn[t.x]>t.d) mn[t.x]=t.d,q.push(t);//如果原来这个点已经可以被更优的所更新,那就不放到队列里面。
if(j>=)
{
t.x=st[a[i].y]+j-;
t.d=dis[st[]+j];
if(mn[t.x]>t.d) mn[t.x]=t.d,q.push(t);
}
}
}
while(!q.empty() && !bk)
{
while(!q.empty())
{
t=q.top();q.pop();
if(dis[t.x]==-)
{
dis[t.x]=t.d;
y=t.x;
if(y==st[n]) bk=;
//如果“目标点n 用完了K次机会”这个状态到1的最短路已经算出来了,那一定是最优的,其它的都不用算了。加了这句话从10s+跑到了0.6s。
break;
}
}
for(int i=first[g[y]];i;i=a[i].next)
{
t.x=st[a[i].y]+id[y];
t.d=dis[y]+a[i].d;
if(dis[t.x]==- && mn[t.x]>t.d) mn[t.x]=t.d,q.push(t);
if(id[y]>=)
{
t.x=st[a[i].y]+id[y]-;
t.d=dis[y];
if(dis[t.x]==- && mn[t.x]>t.d) mn[t.x]=t.d,q.push(t);
}
}
}
} int main()
{
// freopen("a.in","r",stdin);
freopen("revamp.in","r",stdin);
freopen("revamp.out","w",stdout);
scanf("%d%d%d",&n,&m,&K);
len=;num=;
memset(first,,sizeof(first));
for(int i=;i<=m;i++)
{
int x,y;LL d;
scanf("%d%d%lld",&x,&y,&d);
ins(x,y,d);
ins(y,x,d);
}
for(int i=;i<=n;i++)
for(int j=;j<=K;j++)
{
g[++num]=i,id[num]=j;
if(j==) st[i]=num;
} dijkstra();
// for(int i=1;i<=num;i++) if(dis[i]!=-1) printf("%d g = %d id = %d dis = %lld\n",i,g[i],id[i],dis[i]);
LL ans=INF;
for(int i=st[n];i<=st[n]+K;i++)
if(dis[i]!=-) ans=minn(ans,dis[i]);
printf("%lld\n",ans);
return ;
}
【bzo1579】拆点+dijkstra优先队列优化+其他优化的更多相关文章
- 地铁 Dijkstra(优先队列优化) 湖南省第12届省赛
传送门:地铁 思路:拆点,最短路:拆点比较复杂,所以对边进行最短路,spfa会tle,所以改用Dijkstra(优先队列优化) 模板 /******************************** ...
- 晴天小猪历险记之Hill(Dijkstra优先队列优化)
描述 这一天,他来到了一座深山的山脚下,因为只有这座深山中的一位隐者才知道这种药草的所在.但是上山的路错综复杂,由于小小猪的病情,晴天小猪想找一条需时最少的路到达山顶,但现在它一头雾水,所以向你求助. ...
- (模板)poj2387(dijkstra+优先队列优化模板题)
题目链接:https://vjudge.net/problem/POJ-2387 题意:给n个点(<=1000),m条边(<=2000),求结点n到结点1的最短路. 思路:dijkstra ...
- dijkstra与他的优化!!!
目录 SPFA已死,有事烧纸 Dijkstra 配对堆 引言 讲解 合并 修改 弹出堆顶pop 代码 结合! 1 2 @ SPFA已死,有事烧纸 其实我本人也是一个SPFA的忠诚用户,至少我的最少费用 ...
- Til the Cows Come Home 最短路Dijkstra+bellman(普通+优化)
Til the Cows Come Home 最短路Dijkstra+bellman(普通+优化) 贝西在田里,想在农夫约翰叫醒她早上挤奶之前回到谷仓尽可能多地睡一觉.贝西需要她的美梦,所以她想尽快回 ...
- POJ 3268 Silver Cow Party (Dijkstra + 优先队列)
题意:由n个牧场,编号1到n.每个牧场有一头牛.现在在牧场x举办party,每头牛都去参加,然后再回到自己的牧场.牧场之间会有一些单向的路.每头牛都会让自己往返的路程最短.问所有牛当中最长的往返路程是 ...
- 【poj 1724】 ROADS 最短路(dijkstra+优先队列)
ROADS Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12436 Accepted: 4591 Description N ...
- spark优化之优化数据结构
概序: 要减少内存的消耗,除了使用高效的序列化类库以外,还有一个很重要的事情,就是优化数据结构.从而避免Java语法特性中所导致的额外内存的开销,比如基于指针的Java数据结构,以及包装类型. 有一个 ...
- POJ 1511 - Invitation Cards (dijkstra优先队列)
题目链接:http://poj.org/problem?id=1511 就是求从起点到其他点的最短距离加上其他点到起点的最短距离的和 , 注意路是单向的. 因为点和边很多, 所以用dijkstra优先 ...
随机推荐
- TCP系列34—窗口管理&流控—8、缓存自动调整
一.概述 我们之前介绍过一种具有大的带宽时延乘积(band-delay product.BDP)的网络,这种网络称为长肥网络(LongFatNetwork,即LFN).我们想象一种简单的场景,假设发送 ...
- 访问方式由http改为https curl:(51)
系统访问由http变为https,先申请了CA证书,然后win下浏览器访问时没问题的,但是linux下通过curl的方式访问就报错: curl:(51) SSLcertificate subject ...
- PAT 1052 卖个萌
https://pintia.cn/problem-sets/994805260223102976/problems/994805273883951104 萌萌哒表情符号通常由“手”.“眼”.“口”三 ...
- 判断滚动条滚动到document底部
滚动条没有实际的高度.只是为了呈现效果才在外型上面有长度. 在js当中也没有提供滚动条的高度API. 参考了网上有关资料:判断滚动条到底部的基本逻辑是滚动条滚动的高度加上视口的高度,正好是docume ...
- win7 php连接远程oracle
<?php /* 先下载oracle客户端 下载地址 http://www.oracle.com/technetwork/topics/winx64soft-089540.html 下载如下三个 ...
- 爬虫之手机APP抓包教程-亲测HTTP和HTTPS均可实现
当下很多网站都有做自己的APP端产品,一个优秀的爬虫工程师,必须能够绕过难爬取点而取捷径,这是皆大欢喜的.但是在网上收罗和查阅了无数文档和资料,本人亲测无数次,均不能正常获取HTTPS数据,究其原因是 ...
- asp.net AES加密跟PHP的一致,将加密的2进制byte[]转换为16进制byte[] 的字符串获得
<?php class AESUtil { public static function encrypt($input, $key) { $size = mcrypt_get_block_siz ...
- CentOS 文本操作命令
1.cat 用于查看纯文本文件,显示行号,加-n参数,适合内容较少的情况 2.more 用于查看纯文本文件,适合内容较多的情况 3.less 用于查看纯文本文件,可以上下翻页 4.head 用于查看纯 ...
- [bzoj4391] [Usaco2015 dec]High Card Low Card 贪心 线段树
---题面--- 题解: 观察到以决策点为分界线,以点数大的赢为比较方式的游戏都是它的前缀,反之以点数小的赢为比较方式的都是它的后缀,也就是答案是由两段答案拼凑起来的. 如果不考虑判断胜负的条件的变化 ...
- HDOJ(HDU).4508 湫湫系列故事――减肥记I (DP 完全背包)
HDOJ(HDU).4508 湫湫系列故事――减肥记I (DP 完全背包) 题意分析 裸完全背包 代码总览 #include <iostream> #include <cstdio& ...