UVA-10000 Longest Paths (SPFA最短路算法)

本文介绍了一种解决单源最长路径问题的SPFA算法,并通过实例展示了如何利用该算法来帮助朋友计算从起始点到目的地所需的时间,避免因选择最长路径而迟到的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Longest Paths
Time Limit:3000MS     Memory Limit:0KB  
Description
  Longest Paths 
It is a well known fact that some people do not have their social abilities completely enabled. One example is the lack of talent for calculating distances and intervals of time. This causes some people to always choose the longest way to go from one place to another, with the consequence that they are late to whatever appointments they have, including weddings and programming contests. This can be highly annoying for their friends.
César has this kind of problem. When he has to go from one point to another he realizes that he has to visit many people, and thus always chooses the longest path. One of César's friends, Felipe, has understood the nature of the problem. Felipe thinks that with the help of a computer he might be able to calculate the time that César is going to need to arrive to his destination. That way he could spend his time in something more enjoyable than waiting for César.

Your goal is to help Felipe developing a program that computes the length of the longest path that can be constructed in a given graph from a given starting point (César's residence). You can assume that the graph has no cycles (there is no path from any node to itself), so César will reach his destination in a finite time. In the same line of reasoning, nodes are not considered directly connected to themselves.
Input 
The input consists of a number of cases. The first line on each case contains a positive number n (  $1 < n \le 100$) that specifies the number of points that César might visit (i.e., the number of nodes in the graph).
A value of n = 0 indicates the end of the input.

After this, a second number s is provided, indicating the starting point in César's journey (  $1 \le s \le n$). Then, you are given a list of pairs of places p and q, one pair per line, with the places on each line separated by white-space. The pair ``$p \ q$" indicates that César can visit q after p.
A pair of zeros (``0 0") indicates the end of the case.

As mentioned before, you can assume that the graphs provided will not be cyclic.
Output 
For each test case you have to find the length of the longest path that begins at the starting place. You also have to print the number of the final place of such longest path. If there are several paths of maximum length, print the final place with smallest number.

Print a new line after each test case.
Sample Input 
2
1
1 2
0 0
5
3
1 2
3 5
3 1
2 4
4 5
0 0
5
5
5 1
5 2
5 3
5 4
4 1
4 2
0 0
0
Sample Output 
Case 1: The longest path from 1 has length 1, finishing at 2.

Case 2: The longest path from 3 has length 4, finishing at 5.

Case 3: The longest path from 5 has length 2, finishing at 1.

题意:给出一个地图n个点和起点s求按照路径所能走的单源最长路,由于图中没有回路,因此可以用SPFA算法。

      SPFA(Shortest Path Faster Algorithm)算法是求单源最短路径的一种算法,在Bellman-ford算法的基础上加上一个队列优化,减少了冗余的松弛操作,是一种高效的最短路算法。

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int dist[101];//保存当前能到达i的最长路径
int f[101][101];//邻接表保存i出边的邻接点
int que[101];//队列
int use[101];//use=1表示在队列中
int main()
{
	int n,s,i,x,y,maxl,st,ed,e,j,t=0;
	while(scanf("%d",&n)&&n)
	{
		j=0;
		scanf("%d",&s);
		for(i=1;i<=n;i++)
		{
			dist[i]=0;
			f[i][0]=0;
			use[i]=0;
		}
		que[1]=s;//起点入队列
		use[s]=1;
		while(scanf("%d%d",&x,&y)&&(x||y))
			f[x][++f[x][0]]=y;
		maxl=-1;e=0;
		st=0;ed=1;
		while(st!=ed)
		{
			st=(++st)%101;
			int k=que[st];
			use[k]=0;
			if(dist[k]>maxl||(dist[k]==maxl&&k<e)) e=k,maxl=dist[k];
			for(i=1;i<=f[k][0];i++)//每取队列首节点,对所有出边邻接点进行松弛操作(dist更新)
			{                      //若该点没在队列就进队列
				int z=f[k][i];
				if(dist[z]<(dist[k]+1)) 
				{
					dist[z]=dist[k]+1;
					if(!use[z]) {
						ed=(++ed)%101;
						que[ed]=z;
						use[z]=1;
				}
				}
			}
		}
		printf("Case %d: The longest path from %d has length %d, finishing at %d.\n\n",++t,s,maxl,e);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值