【BZOJ】1579: [Usaco2009 Feb]Revamping Trails 道路升级
【算法】分层图最短路
【题解】
考虑k层一模一样的图,然后每个夹层都在每条边的位置新加从上一层跨越到下一层的边权为0的边,这样至多选择k条边置为0。
然后考虑方便的写法。
SPFA
第一次SPFA计算常规最短路(顶层)。
之后k次SPFA,松弛操作加上可以从上一层节点直接获取最短路(即相当于省一条边)
这样可以保证一次SPFA最多只有一条边省略,因为你要么从上一层前一个点下来,其实是获取上一层前一个点的最短路。
要么从前面一个点过来,其实是获取本层的最短路,本层最短路最多从上面下来一次。
因为只与上一层有关,开滚动数组。
SPFA记得SLF优化,不然较慢!
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxm=,maxn=;
struct edge{int v,w,from;}e[maxm*];
int first[maxn],X,n,m,k,q[],tot=;
long long d[][maxn];
bool vis[maxn];
void insert(int u,int v,int w)
{tot++;e[tot].v=v;e[tot].w=w;e[tot].from=first[u];first[u]=tot;}
void spfa()
{
memset(vis,,n+);
memset(d[X],0x3f,*(n+));
int head=,tail=;q[]=;vis[]=;d[X][]=;
while(head!=tail)
{
int x=q[head++];if(head>)head=;
for(int i=first[x];i;i=e[i].from)
if(d[X][e[i].v]>d[X][x]+e[i].w)
{
int y=e[i].v;
d[X][y]=d[X][x]+e[i].w;
if(!vis[e[i].v])
{
if(d[X][y]<d[X][q[head]]){head--;if(head<)head=;q[head]=y;}
else{q[tail++]=y;if(tail>)tail=;}
vis[e[i].v]=;
}
}
vis[x]=;
}
// for(int i=1;i<=n;i++)printf("%d ",d[X][i]);printf("\n");
}
void spfas()
{
// for(int i=1;i<=n;i++)d[X][i]=d[1-X][i];
memset(d[X],0x3f,*(n+));
int head=,tail=;q[]=;vis[]=;d[X][]=;
while(head!=tail)
{
int x=q[head++];if(head>)head=;//printf("q %d",x);
for(int i=first[x];i;i=e[i].from)
if(d[X][e[i].v]>min(d[X][x]+e[i].w,d[-X][x]))
{
int y=e[i].v;
d[X][y]=min(d[X][x]+e[i].w,d[-X][x]);
if(!vis[e[i].v])
{
if(d[X][y]<d[X][q[head]]){head--;if(head<)head=;q[head]=y;}
else{q[tail++]=y;if(tail>)tail=;}
vis[e[i].v]=;
}
}
vis[x]=;
}
// for(int i=1;i<=n;i++)printf("%d ",d[X][i]);printf("\n");
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=;i<=m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
insert(u,v,w);
insert(v,u,w);
}
X=;
spfa();
for(int i=;i<=k;i++)
{
X=-X;
spfas();
}
printf("%lld",d[X][n]);
return ;
}
Dijkstra
效率相似,但是写法简单很多,只要记录多一维层次,每次更新的时候附带上到下一层的更新,然后根据dij每次选择最短的更新的特点,第一次到达n就是答案了。
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn=;
struct edge{int v,w,from;}e[maxn];
struct cyc{
int x,k,d;
bool operator < (const cyc &a)const{
return d>a.d;
}
};
priority_queue<cyc>q;
int n,m,first[maxn],tot,d[maxn][],kind; void insert(int u,int v,int w){
tot++;e[tot].v=v;e[tot].w=w;e[tot].from=first[u];first[u]=tot;
tot++;e[tot].v=u;e[tot].w=w;e[tot].from=first[v];first[v]=tot;
}
int dijkstra(){
q.push((cyc){,,});
memset(d,0x3f,sizeof(d));
d[][]=;
while(!q.empty()){
cyc x=q.top();q.pop();
if(x.d!=d[x.x][x.k])continue;
if(x.x==n)return x.d;
for(int i=first[x.x];i;i=e[i].from){
if(d[e[i].v][x.k]>d[x.x][x.k]+e[i].w){d[e[i].v][x.k]=d[x.x][x.k]+e[i].w;q.push((cyc){e[i].v,x.k,d[e[i].v][x.k]});}
if(x.k<kind&&d[e[i].v][x.k+]>d[x.x][x.k]){d[e[i].v][x.k+]=d[x.x][x.k];q.push((cyc){e[i].v,x.k+,d[e[i].v][x.k+]});}
}
}
return ;
}
int main(){
scanf("%d%d%d",&n,&m,&kind);
int u,v,w;
for(int i=;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);
insert(u,v,w);
}
printf("%d",dijkstra());
return ;
}
【BZOJ】1579: [Usaco2009 Feb]Revamping Trails 道路升级的更多相关文章
- Bzoj 1579: [Usaco2009 Feb]Revamping Trails 道路升级 dijkstra,堆,分层图
1579: [Usaco2009 Feb]Revamping Trails 道路升级 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1573 Solv ...
- BZOJ 1579: [Usaco2009 Feb]Revamping Trails 道路升级( 最短路 )
最短路...多加一维表示更新了多少条路 -------------------------------------------------------------------------------- ...
- bzoj 1579: [Usaco2009 Feb]Revamping Trails 道路升级 -- 分层图最短路
1579: [Usaco2009 Feb]Revamping Trails 道路升级 Time Limit: 10 Sec Memory Limit: 64 MB Description 每天,农夫 ...
- bzoj 1579: [Usaco2009 Feb]Revamping Trails 道路升级 优先队列+dij
1579: [Usaco2009 Feb]Revamping Trails 道路升级 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1768 Solv ...
- bzoj 1579: [Usaco2009 Feb]Revamping Trails 道路升级——分层图+dijkstra
Description 每天,农夫John需要经过一些道路去检查牛棚N里面的牛. 农场上有M(1<=M<=50,000)条双向泥土道路,编号为1..M. 道路i连接牛棚P1_i和P2_i ...
- BZOJ 1579 [Usaco2009 Feb]Revamping Trails 道路升级:dijkstra 分层图【将k条边改为0】
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1579 题意: 给你一个无向图,n个点,m条边,每条边有边权w[i]. 你可以将其中的k(k ...
- BZOJ 1579: [Usaco2009 Feb]Revamping Trails 道路升级 分层图最短路 + Dijkstra
Description 每天,农夫John需要经过一些道路去检查牛棚N里面的牛. 农场上有M(1<=M<=50,000)条双向泥土道路,编号为1..M. 道路i连接牛棚P1_i和P2_i ...
- bzoj 1579: [Usaco2009 Feb]Revamping Trails 道路升级【分层图+spfa】
至死不用dijskstra系列2333,洛谷上T了一个点,开了O2才过 基本想法是建立分层图,就是建k+1层原图,然后相邻两层之间把原图的边在上一层的起点与下一层的终点连起来,边权为0,表示免了这条边 ...
- BZOJ 1579 [Usaco2009 Feb]Revamping Trails 道路升级
堆优化的dijkstra. 把一个点拆成k个. 日常空间要开炸一次.. //Twenty #include<cstdio> #include<cstring> #include ...
- 【BZOJ 1579】 1579: [Usaco2009 Feb]Revamping Trails 道路升级 (最短路)
1579: [Usaco2009 Feb]Revamping Trails 道路升级 Description 每天,农夫John需要经过一些道路去检查牛棚N里面的牛. 农场上有M(1<=M< ...
随机推荐
- 指纹识别人脸识别 iOS
//1.判断iOS8及以后的版本 if([UIDevice currentDevice].systemVersion.doubleValue >= 8.0){ //从iPhone5S开始,出现指 ...
- 设置socket接收和发送超时的一种方式
Linux环境设置Socket接收和发送超时: 须如下定义:struct timeval timeout = {3,0}; //设置发送超时setsockopt(socket,SOL_SOCKET, ...
- json与python解析
1.json.dumps 将 Python 对象编码成 JSON 字符串 json.loads 将已编码的 JSON 字符串解码为 Python 对象 2.json.dump() ...
- SPRITEKIT游戏框架之关于PHYSICS物理引擎属性
Spritekit提供了一个默认的物理模拟系统,用来模拟真实物理世界,可以使得编程者将注意力从力学碰撞和重力模拟的计算中解放出来,通过简单地代码来实现物理碰撞的模拟,而将注意力集中在更需要花费精力的地 ...
- CSS层叠样式表的解释
css: 在标签上设置style属性css注释: /*z注释内容*/css样式的编写位置: 1.在标签的的style属性里 2.在head里面,style标签中写样式 ...
- 软件工程项目组Z.XML会议记录 2013/09/14
软件工程项目组Z.XML会议记录 [例会时间]2013年9月14日星期六21:00-22:30 [例会形式]小组讨论 [例会地点]新主楼A1025 [例会主持]李孟 [会议记录]李孟 会议整体流程 一 ...
- gradle在build之后执行任务
在打包后一般会有copy jar文件的需求. 先在build.gradle文件中定义你的task: task myCopy{ println "some copy code..." ...
- sc"
2.11 题目:二叉搜索树中的最近公共祖先 2.12 设计思路 if 树中不存在 u 或 v 错误 结束程序 定义 p 指向根节点 while true do: if p->key大于 u 和 ...
- Spark中如何生成Avro文件
研究spark的目的之一就是要取代MR,目前我司MR的一个典型应用场景即为生成Avro文件,然后加载到HIVE表里,所以如何在Spark中生成Avro文件,就是必然之路了. 我本人由于对java不熟, ...
- Oracle中SQL语言介绍以及基本用法
一.SQL语言支持如下类别命令 1.数据定义语言(DDL):CREATE(创建).ALTER(更改) 和 DROP(删除)命令 1.1 CREATE (创建表,表空间,用户, 索引, 视图, 同义词 ...