Mzc和体委的争夺战(Dijkstra算法的思考与尝试以及与SPFA算法的对比)
来源:互联网 发布:越狱录屏软件 编辑:程序博客网 时间:2024/06/03 22:00
Mzc和体委的争夺战
–(Dijkstra算法的思考与尝试以及与SPFA算法的对比)
(来源:Luogu)
题目描述
mzc家很有钱(开玩笑),他家有n个男家丁(做过前三弹的都知道)。但如此之多的男家丁吸引来了我们的体委(矮胖小伙),他要来与mzc争夺男家丁。
mzc很生气,决定与其决斗,但cat的体力确实有些不稳定,所以他需要你来帮他计算一下最短需要的时间。
输入输出格式
输入格式:
第一行有两个数n,m,n表示有n个停留站,m表示共有m条路。
之后m行,每行三个数a[i],b[i],c[i],表示第a[i]个停留站到第b[i]个停留站需要c[i]的时间。(无向)
输出格式:
一行,输出1到m最短时间。
输入输出样例
输入样例#1:
5 8
1 2 3
2 3 4
3 4 5
4 5 6
1 3 4
2 4 7
2 5 8
1 5 100
输出样例#1:
11
说明
n<=2500
Dijkstra算法
–单源最短路
先看一下这个图解,有助于我们更好地回忆这个算法。
(GIF来自网络)
值得注意的是该算法要求图中不存在负权边,而这也正是SPFA的优点(有种喧宾夺主的感觉)。
它就是以起始点为中心向外求直接相连的最短路,直到扩展到终点为止。其实主要内容看一看这个图就好了。
对于这个题而言,我们需要注意Dijkstra不会判重边,所以在读入的时候要处理一下,让重边取最短的一条。
接下来展示一下代码:
Dijkstra代码
#include<iostream>#include<cstring>using namespace std;int i,j,k,m,n;int a[2501][2501];int f[2501];int b[2501];int r(){ char ch=getchar(); int ans=0; while(ch<'0'||ch>'9') { ch=getchar(); } while(ch>='0'&&ch<='9') { ans*=10; ans+=ch-'0'; ch=getchar(); } return ans;}void dijk(int x){ b[x]=1; for(int i=1;i<=n;i++) { if(a[x][i]) f[i]=a[x][i]; } f[x]=0; for(int i=1;i<=n;i++) { int k=0; int minn=0x7fffff,mi; for(int j=1;j<=n;j++) { if(!b[j]&&f[j]<minn) { minn=f[j]; mi=j; } } b[mi]=1; for(int j=1;j<=n;j++) { if(minn+a[mi][j]<f[j]) f[j]=minn+a[mi][j]; } }}int main(){ n=r(),m=r(); for(i=1;i<=n;i++) f[i]=1000000000; memset(a,0x7f,sizeof(a)); int x,y,z; for(i=1;i<=m;i++) { x=r(),y=r(),z=r(); if(z<a[x][y]) {a[x][y]=z; a[y][x]=z;} } dijk(1); cout<<f[n];}
SPFA代码
#include<iostream>#include<cstdio>#include<cstdlib>#include<queue>#include<cstring>using namespace std;queue<int>q;int i,j,m,n,st,en,x,y,w;int s[2501],gs[2501];int len[2501];struct data{ int d; int v; struct data *nxt;};struct data a[5000001],*head;int r(){ int ans=0; char ch=getchar(); while(ch<'0'||ch>'9') ch=getchar(); while(ch>='0'&&ch<='9') { ans*=10; ans+=ch-'0'; ch=getchar(); } return ans;}void spfa(int xx){ struct data *p=&a[s[xx]]; while(!q.empty()) { p=&a[s[q.front()]]; xx=q.front(); q.pop(); while(p!=NULL) { if(len[p->d]>p->v+len[xx]) { q.push(p->d); len[p->d]=p->v+len[xx]; } p=p->nxt; } }}int main(){ memset(len,0x7f7f7f,sizeof(len)); n=r(),m=r(),st=1,en=n; len[st]=0; for(i=1;i<=m;i++) { x=r(),y=r(),w=r(); a[gs[x]].nxt=&a[i*2-1]; a[gs[y]].nxt=&a[i*2]; gs[x]=i*2-1; gs[y]=i*2; if(!s[x]) s[x]=i*2-1; if(!s[y]) s[y]=i*2; a[i*2-1].d=y,a[i*2-1].v=w; a[i*2].d=x,a[i*2].v=w; } q.push(st); spfa(st); cout<<len[en];}
Dijkstra
10ms/35761kB
85ms/35761kB
10ms/35761kB
12ms/35761kB
16ms/35761kB
19ms/35761kB
75ms/35761kB
60ms/35761kB
63ms/35761kB
109ms/35761kB
耗时/内存 459ms , 35761kb
SPFA
4ms/1371kB
3ms/1378kB
2ms/92742kB
7ms/1691kB
4ms/1433kB
403ms/92742kB
164ms/5226kB
39ms/2367kB
107ms/5246kB
6ms/1703kB
耗时/内存 739ms , 92742kb
- Mzc和体委的争夺战(Dijkstra算法的思考与尝试以及与SPFA算法的对比)
- heap+dijkstra与SPFA的对比
- 关于对Tarjan算法的思考与尝试
- (最短路径算法整理)dijkstra、floyd、bellman-ford、spfa算法模板的整理与介绍
- dijkstra算法与prim算法的区别
- Prim算法与Dijkstra算法的区别
- Prim算法与Dijkstra算法的区别
- dijkstra算法与prim算法的区别
- Prim算法与Dijkstra算法的区别
- Dijkstra算法与Prim算法的区别
- dijkstra算法与prim算法的区别
- Dijkstra算法与Prim算法的异同
- hdu2066一个人的旅行(dijkstra和spfa算法)
- 最短路径问题的Dijkstra和SPFA算法总结
- Bellman-ford算法与Dijkstra算法(RIP和OSPF的基本算法)
- Bellman-ford算法与Dijkstra算法(RIP和OSPF的基本算法)
- 最短路的三种算法(Floyd、Dijkstra、SPFA)
- Prim算法与Dijkstra的异同
- Git提示fatal: remote origin already exists解决办法:之前添加过远程库
- Android中圆角显示EditText,并且只能显示一行
- C++ —内存对齐
- linux下grep查找进程
- 70. Climbing Stairs
- Mzc和体委的争夺战(Dijkstra算法的思考与尝试以及与SPFA算法的对比)
- 如何创建快捷方式并添加到开始菜单、桌面、任务栏....
- Java 枚举(enum) 详解7种常见的用法
- CodeForces 831C Jury Marks(set)
- UVA 11292
- 网页设计配色方法论:配色秩序
- USACO 3.1.1 网络布线
- Jenkins:解决Console Output中文乱码问题
- opengl坐标系