【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< ...
随机推荐
- malloc函数分配失败处理的严重性
本次在实际测试情况下,发现程序无缘无故的异常,导致看门狗超时复位,经过排查是malloc函数分配失败的时候,依然对指针进行了操作,导致异常.以前没重视这个问题是因为,总觉的malloc基本都会成功的, ...
- Java检测端口的占用情况
突然间想到这个问题,在网上搜了一下 http://blog.csdn.net/danieluk/article/details/18518175 网上有很多文章都是用上面那个方法来解决这个问题的,总感 ...
- Assetbundle2
Assetbundle可以将Prefab封装起来,这是多么方便啊! 而且我也强烈建议大家将Prefab封装成Assetbundle,因为Prefab可以将游戏对象身上带的游戏游戏组件.游戏脚本.材质都 ...
- nohup追加日志
背景:用脚本部署Spring Boot应用,用nohup命令进行后台运行 之前的日志处理: nohup command > myout.file 2>&1 & 导致每次用s ...
- 【iOS开发】创建单例的两种方法
创建一个单例很多办法.我先列举一个苹果官方文档中的写法. [cpp] view plaincopy static AccountManager *DefaultManager = nil; + ( ...
- 列数不固定时怎么使用el-tabel展示数据
<el-table :data="contents" stripe> <el-table-column v-for="(item, index) in ...
- Hibernate常用方法之_插入
1.使用session的save方法进行插入 public void saveUser(User user){ Session session = null; Transaction transact ...
- sessionStorage的用法总结
sessionStorage用于本地存储一个会话(session)中的数据,这些数据只有在同一个会话中的页面才能访问并且当会话结束后数据也随之销毁.因此sessionStorage不是一种持久化的本地 ...
- bzoj1726 第二短路
一道严格次短路题,WA了一下午回家才发现bellman_ford中的vis [ o ] = false 写成了 vis [ S ] = false.被自己脑残了一脸.... #include<c ...
- WIN8 打开图片内置管理员无法激活此应用
1.运行 gpedit.msc 2.计算机配置.windows设置.安全设置.本地策略.安全选项.“用户账户控制用于内置管理员账户的管理员批准模式” 改为已启用 3.重启电脑