【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优先 ...
随机推荐
- Daily Scrum8
今天我们小组开会内容分为以下部分: part 1: 说明了search.match.upload.download功能实现流程: part 2:针对用户积分模块的任务分配: ◆Part 1 searc ...
- ArrayList遍历(JAVA)
假如有个ArrayList变量如下: ArrayList<String> list = new ArrayList<String>(); list.add("arra ...
- C语言的世界
大家好,我是一名大一的学生,我叫陈由钧,我来自计算机系,一开始选择这门专业的时候,是出于对计算机的热爱,我喜欢计算机,喜欢没事琢磨琢磨计算的各种程序,各种软件,所以我选择学习计算机这门专业,第一周我就 ...
- CentOS/Linux 开放80、8080端口或者开放某个端口
装载系统的时候只开启了22端口.结果再装完Nginx+php+mysql 后不能访问网站. iptables -L -n 查看防火墙设置发现没开启80端口 由于Linux防火墙默认是关闭的.可以用两种 ...
- Android------BottonTabBar
前言:一款简单好用封装好的AndroidUI控件,底部导航栏. 1.使用 1.1添加 compile 'com.hjm:BottomTabBar:1.1.1' 1.2 activity_main. ...
- jira & analytics
jira & analytics jira 代码有毒呀 http://jira.xgqfrms.xyz:8888/rest/analytics/1.0/publish/bulk { resou ...
- BZOJ 1789 Y形项链(思维)
这题类似于1787,最后的节点一定是两点的LCA,这里也就是两个字符串的最长公共前缀. # include <cstdio> # include <cstring> # inc ...
- 【bzoj1596】[Usaco2008 Jan]电话网络 树形dp
题目描述 Farmer John决定为他的所有奶牛都配备手机,以此鼓励她们互相交流.不过,为此FJ必须在奶牛们居住的N(1 <= N <= 10,000)块草地中选一些建上无线电通讯塔,来 ...
- 【bzoj1212】[HNOI2004]L语言 AC自动机
题目描述 标点符号的出现晚于文字的出现,所以以前的语言都是没有标点的.现在你要处理的就是一段没有标点的文章. 一段文章T是由若干小写字母构成.一个单词W也是由若干小写字母构成.一个字典D是若干个单词的 ...
- [NOIP2016 TG D2T3]愤怒的小鸟
题目大意:有一架弹弓位于(0,0)处,每次可以用它向第一象限发射一只小鸟,飞行轨迹均为形如y=ax2+bxy=ax+bx2 y=ax2+bx的曲线,且必须满足a<0(即是下开口的) 平面的第一象 ...