【算法】分层图最短路

【题解】

考虑k层一模一样的图,然后每个夹层都在每条边的位置新加从上一层跨越到下一层的边权为0的边,这样至多选择k条边置为0。

然后考虑方便的写法。

SPFA

第一次SPFA计算常规最短路(顶层)。

之后k次SPFA,松弛操作加上可以从上一层节点直接获取最短路(即相当于省一条边)

这样可以保证一次SPFA最多只有一条边省略,因为你要么从上一层前一个点下来,其实是获取上一层前一个点的最短路。

要么从前面一个点过来,其实是获取本层的最短路,本层最短路最多从上面下来一次。

因为只与上一层有关,开滚动数组。

SPFA记得SLF优化,不然较慢!

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxm=50010,maxn=10010;
struct edge{int v,w,from;}e[maxm*3];
int first[maxn],X,n,m,k,q[10010],tot=0;
long long d[2][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,0,n+1);memset(d[X],0x3f,8*(n+1));int head=0,tail=1;q[0]=1;vis[1]=1;d[X][1]=0;while(head!=tail){int x=q[head++];if(head>10000)head=0;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<0)head=10000;q[head]=y;}else{q[tail++]=y;if(tail>10000)tail=0;}vis[e[i].v]=1;}}vis[x]=0;}
//    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,8*(n+1));int head=0,tail=1;q[0]=1;vis[1]=1;d[X][1]=0;while(head!=tail){int x=q[head++];if(head>10000)head=0;//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[1-X][x])){int y=e[i].v;d[X][y]=min(d[X][x]+e[i].w,d[1-X][x]);if(!vis[e[i].v]){if(d[X][y]<d[X][q[head]]){head--;if(head<0)head=10000;q[head]=y;}else{q[tail++]=y;if(tail>10000)tail=0;}vis[e[i].v]=1;}}vis[x]=0;}
//    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=1;i<=m;i++){int u,v,w;scanf("%d%d%d",&u,&v,&w);insert(u,v,w);insert(v,u,w);}X=0;spfa();for(int i=1;i<=k;i++){X=1-X;spfas();}printf("%lld",d[X][n]);return 0;
}

View Code

Dijkstra

效率相似,但是写法简单很多,只要记录多一维层次,每次更新的时候附带上到下一层的更新,然后根据dij每次选择最短的更新的特点,第一次到达n就是答案了。

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn=100010;
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][30],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){1,0,0});memset(d,0x3f,sizeof(d));d[1][0]=0;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+1]>d[x.x][x.k]){d[e[i].v][x.k+1]=d[x.x][x.k];q.push((cyc){e[i].v,x.k+1,d[e[i].v][x.k+1]});}}}return 0;
}
int main(){scanf("%d%d%d",&n,&m,&kind);int u,v,w;for(int i=1;i<=m;i++){scanf("%d%d%d",&u,&v,&w);insert(u,v,w);}printf("%d",dijkstra());return 0;
}

View Code

转载于:https://www.cnblogs.com/onioncyc/p/6637133.html

【BZOJ】1579: [Usaco2009 Feb]Revamping Trails 道路升级相关推荐

  1. bzoj 1579: [Usaco2009 Feb]Revamping Trails 道路升级【分层图+spfa】

    至死不用dijskstra系列2333,洛谷上T了一个点,开了O2才过 基本想法是建立分层图,就是建k+1层原图,然后相邻两层之间把原图的边在上一层的起点与下一层的终点连起来,边权为0,表示免了这条边 ...

  2. [Usaco2009 Feb]Revamping Trails 道路升级

    题目描述 每天,农夫John需要经过一些道路去检查牛棚N里面的牛. 农场上有M(1<=M<=50,000)条双向泥土道路,编号为1..M. 道路i连接牛棚P1_i和P2_i (1 < ...

  3. bzoj 3398: [Usaco2009 Feb]Bullcow 牡牛和牝牛(DP)

    3398: [Usaco2009 Feb]Bullcow 牡牛和牝牛 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 353  Solved: 248 ...

  4. bzoj 3398 [Usaco2009 Feb]Bullcow 牡牛和牝牛——前缀和优化dp / 排列组合

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3398 好简单呀.而且是自己想出来的. dp[ i ]表示最后一个牡牛在 i 的方案数. 当前 ...

  5. bzoj 3398: [Usaco2009 Feb]Bullcow 牡牛和牝牛

    Description 约翰要带N(1≤N≤100000)只牛去参加集会里的展示活动,这些牛可以是牡牛,也可以是牝牛.牛们要站成一排.但是牡牛是好斗的,为了避免牡牛闹出乱子,约翰决定任意两只牡牛之间至 ...

  6. 洛谷 P2939 [USACO09FEB]改造路Revamping Trails

    洛谷 P2939 [USACO09FEB]改造路Revamping Trails Description 约翰一共有N)个牧场.由M条布满尘埃的小径连接.小径可 以双向通行.每天早上约翰从牧场1出发到 ...

  7. 1578: [Usaco2009 Feb]Stock Market 股票市场

    1578: [Usaco2009 Feb]Stock Market 股票市场 Time Limit: 10 Sec  Memory Limit: 64 MB Submit: 414  Solved:  ...

  8. [JLOI 2011]飞行路线[USACO 09FEB]Revamping Trails

    Description Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并 ...

  9. 3398: [Usaco2009 Feb]Bullcow 牡牛和牝牛

    3398: [Usaco2009 Feb]Bullcow 牡牛和牝牛 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 243  Solved: 167 ...

最新文章

  1. linux insight 使用教程,Insight API开源项目分析
  2. C/C++栈溢出的几种解决办法
  3. python:将一个文件转换为二进制文件(binary)
  4. 比较完整的URL验证
  5. Monotone Chain Convex Hull(单调链凸包)
  6. linux 解压缩指令
  7. 最大尺寸分辨率_LG UltraFine 4K显示器重上架苹果商店:尺寸变大,但降为UHD
  8. Codeforces Round #409 C. Voltage Keepsake(二分+思维)
  9. 申请美国大学计算机专业,申请美国大学计算机CS专业的4个要点
  10. 2.(echarts篇)echarts颜色地图边缘高亮
  11. grid 与axis
  12. 储罐液位计算机控制系统,罐区管理系统
  13. 工业4.0时代 个性化定制掀起制造业新篇章
  14. speccpu测试工具介绍和使用说明
  15. Multi-level Feature Fusion Networks with Adaptive Channel Dimensionality Reduction for Remote Sens
  16. socket通信技术
  17. android poi webview,java-Android(4.4)WebView第二次加载时不显示ifra...
  18. 持续集成(CI)工具-----jenkins
  19. PPT结尾页只会写“谢谢”?用这些结尾,让你惊艳全场
  20. JDK1.8下载安装与环境变量配置(Win7)

热门文章

  1. 第二十三:Appium+Pytest实现app并发测试
  2. matlab水蒸气焓值计算_焓变 反应热-化学选修4同步优质系列教案(人教版)
  3. python 数学计算库_Python标准库——数学运算
  4. Spring 源码解析 -- SpringWeb过滤器Filter解析
  5. tomcat运行出现问题(Starting Tomcat v8.0 Server at localhost' has encountered a problem.)
  6. Spring Data Jpa的@DynamicInsert注解和@DynamicUpdate注解
  7. MySQL中的datetime对应Java类型
  8. mysql sql语句提升_mysql基本sql语句大全(提升用语篇)
  9. php读取大文件某行内容,PHP读取和修改大文件的某行内容_PHP教程
  10. 虚拟机环境下ansible方式部署tidb3.0时系统检测不通过