【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< ...
随机推荐
- PowerPC为什么会没落,我自己的反思学习总结
PowerPC为什么会没落? Intel通过酷睿,拉大优势,使得苹果抛弃PowerPC PowerPC当年异常强大,曾经是Xbox的处理器,是Mac的处理器,占据了服务器的半壁江山:当时刚刚接触C ...
- CentOS7安装Oracle 11gR2 图文详解
注:Oracle11gR2 X64安装 一.环境准备 安装包: 1.VMware-workstation-full-11.1.0-2496824.exe 2.CentOS-7-x86_64-DVD-1 ...
- CAS单点登录(一):单点登录与CAS理论介绍
一.什么是单点登录(SSO) 单点登录主要用于多系统集成,即在多个系统中,用户只需要到一个中央服务器登录一次即可访问这些系统中的任何一个,无须多次登录. 单点登录(Single Sign On),简称 ...
- APP功能性测试-4
弱网络测试 使用fiddler模拟低速环境 使用fiddler抓取手机上某个应用的包 手机连接fiddler fiddler 代理地址127.0.0.1默认端口8888 只抓http协议(https, ...
- SQL 语句中 exists和not exists的用法
exists (sql 返回结果集,为真) not exists (sql 不返回结果集,为真) 如下: 表A ID NAME ...
- DOM操作相关案例 模态对话框,简易留言板,js模拟选择器hover,tab选项卡,购物车案例
1.模态框案例 需求: 打开网页时有一个普通的按钮,点击当前按钮显示一个背景图,中心并弹出一个弹出框,点击X的时候会关闭当前的模态框 代码如下: <!DOCTYPE html> <h ...
- 官方文档 恢复备份指南四 Starting and Interacting with the RMAN Client
本章讲: Starting and Exiting RMAN Specifying the Location of RMAN Output ...
- ubuntu 和 centOS 的apache设置
更改ubuntu的网站访问根目录: 在sudo gedit /etc/apache2/sites-enabled/000-default,把 DocumentRoot /var/www #这 ...
- ArcGIS10.2中文版安装和破解教程
http://jingyan.baidu.com/article/e73e26c0cb5c1324adb6a791.html
- fetch_array()与fetch_assoc()的用法
fetch_array()与fetch_assoc()用起来没有什么大的差别,主要是怎么用?fetch_array()如果单独作为while的条件,则能够取出结果集中的所有结果.如果单独作用于结果集, ...