vijos1635 SPFA和FLOYD算法如何打印路径

之前打的spfa或是floyd都只是用来求最短路,对于如何打印路径问题一点都没有概念

可能也是因为对于原理没有很理解的缘故?

总之,之后赶紧看了一下,现在总算是明白了.....MARK一下自己的理解

早晨碰到了一题挺裸的最短路问题:vijos1635

1.首先说说spfa的方法:

其实自己之前打的最多的spfa是在网格上的那种,也就是二维的

一维的需要邻接表+queue

以及对于queue的操作,自己也是醉了

这里贴一个模板(不含打印路径):

#include<cstdio>
#include<cstring>
#include<queue>
#include<iostream>
using namespace std;
const int maxn=10100;
int n,m,k,t,x,y,s,ans=0;
long long tot=0;
struct edge{
	int from,to,w,next;
}e[10100000];
int head[maxn],dist[maxn];
bool vis[maxn];
void add(int x,int y,int z){//邻接表
	e[tot].from=x;
	e[tot].to=y;
	e[tot].w=z;
	e[tot].next=head[x];
	head[x]=tot++;
}
void spfa(int s){
	queue<int>q;
	memset(dist,63,sizeof(dist));
	memset(vis,false,sizeof(vis));//感觉这里的赋值和二维的略有区别,这里是初始值false
	q.push(s);
	dist[s]=0;
	while(!q.empty()){
		int u=q.front();
		q.pop();
		vis[u]=false;②
		for(int i=head[u];i!=-1;i=e[i].next){
			int v=e[i].to;
			if(dist[v]>dist[u]+e[i].w){
				dist[v]=dist[u]+e[i].w;
				if(!vis[v]){         //如果已经入队,或是初始值①
					vis[v]=true;
					q.push(v);
				}
			}
		}
	}
}
int main(){
	scanf("%d",&n);
	memset(head,-1,sizeof(head));//记得head赋值为-1
	for(int i=1;i<=n;i++)
	   for(int j=1;j<=n;j++){
	   	  scanf("%d",&s);
	   	  if(s!=0){
	   	  	  add(i,j,s);
	   	  }
	   }
    spfa(1);
    printf("%d",dist[n]);
    return 0;
}

好好感受一下①和②

对于spfa打印路径问题:

这里就需要用上指针的思想,去找n的前驱

所以如果dist有更新值,那么就记录下,但是这里要理解,

你记录的并不是根据这条路的路径顺序记的

说白了就是,f[1]并不是第一条路径

而是让v->u,这才是f应该做的

   if(dist[v]>dist[u]+e[i].w){
	dist[v]=dist[u]+e[i].w;
	f[v]=u;//在更新值的后面加上这个
	if(!vis[v]){
	vis[v]=true;
	q.push(v);
	}  }

以及调用一个递归函数寻找前驱:

void printpath(int k){
    if(k!=0){
    	printpath(f[k]);
    	printf("%d ",k);
    }
}

2.FLOYD算法:

也是在更新值后面加上一条语句:

k=1-n

i=1-n

j=1-n

if(..>..)

dist[i][j]=dist[i][k]+dist[k][j];

f[i][j]=f[i][k];

 for(v=0; v<n; ++v)
    {
        for(w=v+1; w<n; w++)
        {
            printf("%d ->%d:%d ",v,w,D[v][w]);
            k=P[v][w];                /* 获得第一个路径顶点下标 */
            printf(" path: %d",v);    /* 打印源点 */
            while(k!=w)                /* 如果路径顶点下标不是终点 */
            {
                printf(" -> %d",k);    /* 打印路径顶点 */
                k=P[k][w];            /* 获得下一个路径顶点下标 */
            }
            printf(" -> %d\n",w);    /* 打印终点 */
        }
        printf("\n");
    }

vijos1635 SPFA和FLOYD算法如何打印路径

时间: 2024-12-13 13:27:34

vijos1635 SPFA和FLOYD算法如何打印路径的相关文章

HDU 1385 Minimum Transport Cost(Floyd 最短路 打印路径)

HDU 1385 大意: 有N个城市,然后直接给出这些城市之间的邻接矩阵,矩阵中-1代表那两个城市无道路相连,其他值代表路径长度. 如果一辆汽车经过某个城市,必须要交一定的钱(可能是过路费). 现在要从a城到b城,花费为路径长度之和,再加上除起点与终点外所有城市的过路费之和. 求最小花费,如果有多条路经符合,则输出字典序最小的路径. 思路: Floyd求最短路,打印路径即可. 1 /*--------------------------------------------------------

Floyd算法——保存路径——输出路径 HDU1385

题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1385 参考 http://blog.csdn.net/shuangde800/article/details/8075165 题目大意: 有N个城市,然后直接给出这些城市之间的邻接矩阵,矩阵中-1代表那两个城市无道路相连,其他值代表路径长度. 如果一辆汽车经过某个城市,必须要交一定的钱(可能是过路费). 现在要从a城到b城,花费为路径长度之和,再加上除起点与终点外所有城市的过路费之和. 求最小花费,

hdu 1385 Minimum Transport Cost (Floyd + 字典序打印路径)

Minimum Transport Cost Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7822    Accepted Submission(s): 2028 Problem Description These are N cities in Spring country. Between each pair of cities

最短路算法 :Bellman-ford算法 &amp; Dijkstra算法 &amp; floyd算法 &amp; SPFA算法 详解

 本人QQ :2319411771   邮箱 : [email protected] 若您发现本文有什么错误,请联系我,我会及时改正的,谢谢您的合作! 本文为原创文章,转载请注明出处 本文链接   :http://www.cnblogs.com/Yan-C/p/3916281.html . 很早就想写一下最短路的总结了,但是一直懒,就没有写,这几天又在看最短路,岁没什么长进,但还是加深了点理解. 于是就想写一个大点的总结,要写一个全的. 在本文中因为邻接表在比赛中不如前向星好写,而且前向星效率并

[Python] 弗洛伊德(Floyd)算法求图的直径并记录路径

相关概念 对于一个图G=(V, E),求图中两点u, v间最短路径长度,称为图的最短路径问题.最短路径中最长的称为图的直径. 其中,求图中确定的某两点的最短路径算法,称为单源最短路径算法.求图中任意两点间的最短路径算法,称为多源最短路径算法. 常用的路径算法有: Dijkstra算法 SPFA算法\Bellman-Ford算法 Floyd算法\Floyd-Warshall算法 Johnson算法 其中最经典的是Dijkstra算法和Floyd算法.Floyd算法是多源最短路径算法,可以直接求出图

hihocoder-1089-最短路径Floyd算法

hihocoder-1089-最短路径Floyd算法 #1089 : 最短路径·二:Floyd算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 万圣节的中午,小Hi和小Ho在吃过中饭之后,来到了一个新的鬼屋! 鬼屋中一共有N个地点,分别编号为1..N,这N个地点之间互相有一些道路连通,两个地点之间可能有多条道路连通,但是并不存在一条两端都是同一个地点的道路. 由于没有肚子的压迫,小Hi和小Ho决定好好的逛一逛这个鬼屋,逛着逛着,小Hi产生了这样的问题:鬼屋中任意

L2-001. 紧急救援 (Dijkstra算法打印路径)

作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图.在地图上显示有多个分散的城市和一些连接城市的快速道路.每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上.当其他城市有紧急求助电话给你的时候,你的任务是带领你的救援队尽快赶往事发地,同时,一路上召集尽可能多的救援队. 输入格式: 输入第一行给出4个正整数N.M.S.D,其中N(2<=N<=500)是城市的个数,顺便假设城市的编号为0~(N-1):M是快速道路的条数:S是出发地的城市编号:D是目的地的城市编号.第二行给出

最短路径问题---Floyd算法详解

前言 Genius only means hard-working all one's life. Name:Willam Time:2017/3/8 1.最短路径问题介绍 问题解释: 从图中的某个顶点出发到达另外一个顶点的所经过的边的权重和最小的一条路径,称为最短路径 解决问题的算法: 迪杰斯特拉算法(Dijkstra算法) 弗洛伊德算法(Floyd算法) SPFA算法 之前已经对Dijkstra算法做了介绍(不懂的可以看这篇博客:Dijkstra算法详解),所以这篇博客打算对Floyd算法做

多源最短路径算法—Floyd算法

前言 在图论中,在寻路最短路径中除了Dijkstra算法以外,还有Floyd算法也是非常经典,然而两种算法还是有区别的,Floyd主要计算多源最短路径. 在单源正权值最短路径,我们会用Dijkstra算法来求最短路径,并且算法的思想很简单--贪心算法:每次确定最短路径的一个点然后维护(更新)这个点周围点的距离加入预选队列,等待下一次的抛出确定.但是虽然思想很简单,实现起来是非常复杂的,我们需要邻接矩阵(表)储存长度,需要优先队列(或者每次都比较)维护一个预选点的集合.还要用一个boolean数组