博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
P1339 热浪 最短路径模板题
阅读量:6572 次
发布时间:2019-06-24

本文共 4345 字,大约阅读时间需要 14 分钟。

这么naive的题面一看就是最短路模板题~~~

ok。首先是floyd算法,tts,记得把k放在最外面就行了。

1 #include 
2 #include
3 #include
4 using namespace std; 5 int a[2501][2501]; 6 int main() 7 { 8 int m,n,c,b; 9 memset(a,0x3f,sizeof(a));10 scanf ("%d%d%d%d",&n,&m,&c,&b);11 int x,y,z;12 while(m--)13 {14 scanf ("%d%d%d",&x,&y,&z);15 a[x][y]=z;16 a[y][x]=z;17 }18 for(int k=1;k<=n;k++)19 {20 for(int i=1;i<=n;i++)21 {22 for(int j=1;j<=n;j++)23 {24 a[i][j]=min(a[i][j],a[i][k]+a[k][j]);25 }26 }27 }28 printf("%d",a[c][b]);29 return 0;30 }
Floyd

没有任何的参考价值,除非你要做多源最短路径(☺)

next,SPFA算法,最短路径更快算法(☺),shortest path faster algorithm

思想是这样的:从起点开始入队,然后每次取出一个点,消除标记,轮边松弛。

对于松弛了的边,如果在队中就不用管。否则入队+标记。

然后就能很naive的输出答案了!

注意:当一个点进队超过n次就有负环。

十分规范的模板。

1 #include 
2 #include
3 using namespace std; 4 const int N = 1000010; 5 int n,top; 6 struct Edge 7 { 8 int u,v,len,next,num; 9 }edge[N];10 struct Point11 {12 int dis=0x3f3f3f3f,e,c,num;13 bool vis;14 }point[N];15 16 bool spfa(int k)17 {18 queue
p;19 point[k].vis=1;20 point[k].c++;21 point[k].dis=0;22 p.push(k);23 int op,ed,i;24 while(!p.empty())25 {26 op=p.front();27 p.pop();28 point[op].vis=0;29 i=point[op].e;30 while(i)31 {32 ed=edge[i].v;33 if(point[ed].dis>point[op].dis+edge[i].len)34 {35 point[ed].dis=point[op].dis+edge[i].len;36 if(point[ed].vis) continue;37 point[ed].vis=1;38 p.push(ed);39 point[ed].c++;40 if(point[ed].c>n) return 0;41 }42 i=edge[i].next;43 }44 }45 return true;46 }47 void add(int x,int y,int z)48 {49 top++;50 edge[top].u=x;51 edge[top].v=y;52 edge[top].len=z;53 edge[top].num=top;54 edge[top].next=point[x].e;55 point[x].e=top;56 return;57 }58 int main()59 {60 int m,a,b;61 scanf ("%d%d%d%d",&n,&m,&a,&b);62 for(int i=1;i<=n;i++) point[i].num=i;63 int x,y,z;64 for(int i=1;i<=m;i++)65 {66 scanf ("%d%d%d",&x,&y,&z);67 add(x,y,z);68 add(y,x,z);69 }70 if(!spfa(a)) printf("-1");71 else printf("%d",point[b].dis);72 return 0;73 }
SPFA spfa

 

 

 

接下来是稠密图上的dijkstra算法,di jk s tra(☺)

思想:来个优先队列,dis小的点先出。

起点入队,然后每次取出一个未标记的点标记已读,然后轮边。

如果终点被标记就continue,记得更新i。否则松弛一下,不管有没有成功都入队。

今天刚打的代码,也很规范。

(缺点:边权不能为负)

1 #include 
2 #include
3 using namespace std; 4 const int N = 1000010; 5 int top; 6 struct Edge 7 { 8 int u,v,len,next,num; 9 }edge[N];10 struct Point11 {12 int e,dis=0x3f3f3f3f,c,num;13 bool vis;14 bool operator < (const Point &a) const15 {16 return this->dis > a.dis;17 }18 }point[N];19 20 void dijkstra(int k)21 {22 priority_queue
p;23 p.push(point[k]);24 point[k].vis=1;25 point[k].dis=0;26 int op,ed,i;27 while(!p.empty())28 {29 while((!p.empty())&&(p.top().vis)) p.pop();30 if(p.empty()) break;31 op=p.top().num;32 p.pop();33 point[op].vis=1;34 i=point[op].e;35 while(i)36 {37 ed=edge[i].v;38 if(point[ed].vis) {i=edge[i].next;continue;}39 if(point[ed].dis>point[op].dis+edge[i].len) point[ed].dis=point[op].dis+edge[i].len;40 p.push(point[ed]);41 i=edge[i].next;42 }43 }44 return;45 }46 47 48 void add(int x,int y,int z)49 {50 top++;51 edge[top].u=x;52 edge[top].v=y;53 edge[top].len=z;54 edge[top].num=top;55 edge[top].next=point[x].e;56 point[x].e=top;57 return;58 }59 int main()60 {61 int m,n,a,b;62 scanf ("%d%d%d%d",&n,&m,&a,&b);63 int x,y,z;64 for(int i=1;i<=n;i++) point[i].num=i;65 while(m--)66 {67 scanf ("%d%d%d",&x,&y,&z);68 add(x,y,z);69 add(y,x,z);70 }71 dijkstra(a);72 printf("%d",point[b].dis);73 return 0;74 }
Dijkstra

That's all,thanks for watching.

 

转载于:https://www.cnblogs.com/huyufeifei/p/8579925.html

你可能感兴趣的文章
php fpm安装curl后,nginx出现connect() to unix:/var/run/php5-fpm.sock failed (13: Permission denied)的错误...
查看>>
html表单控件--锁定
查看>>
列类型——字符串类型
查看>>
去除滚动条,内容仍然可以滚动
查看>>
mysql允许远程登录
查看>>
hdu(1596)
查看>>
文件读写
查看>>
csv文件导出
查看>>
对xml的操作使用的类XElement的使用
查看>>
js判断undefined类型
查看>>
Existence and uniqueness theorems for variational problems
查看>>
问题账户需求分析
查看>>
tensorflow 逻辑回归之解决欠拟合问题(一)
查看>>
HDU 5826 physics
查看>>
修改软件源为163的镜像
查看>>
你可能不知道的技术细节:存储过程参数传递的影响
查看>>
[LUOGU] P1962 斐波那契数列
查看>>
正式学习 React(三)番外篇 reactjs性能优化之shouldComponentUpdate
查看>>
后缀数组
查看>>
u3d移动游戏优化规范
查看>>