URAL1004 Sightseeing Trip(Folyd求最小环,打印路径)

2023-10-06 00:01

本文主要是介绍URAL1004 Sightseeing Trip(Folyd求最小环,打印路径),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目:

1004. Sightseeing Trip

Time limit: 0.5 second
Memory limit: 64 MB
There is a travel agency in Adelton town on Zanzibar island. It has decided to offer its clients, besides many other attractions, sightseeing the town. To earn as much as possible from this attraction, the agency has accepted a shrewd decision: it is necessary to find the shortest route which begins and ends at the same place.
Your task is to write a program which finds such a route. In the town there are  N crossing points numbered from 1 to  N and  M two-way roads numbered from 1 to  M. Two crossing points can be connected by multiple roads, but no road connects a crossing point with itself. Each sightseeing route is a sequence of road numbers  y 1, …,  ykk > 2. The road  yi  (1 ≤  i ≤  k − 1) connects crossing points xi and  x i+1, the road  yk connects crossing points  xk and  x 1. All the numbers  x 1, …,  xk should be different. The length of the sightseeing route is the sum of the lengths of all roads on the sightseeing route, i.e. L( y 1) + L( y 2) + … + L( yk) where L( yi) is the length of the road  yi (1 ≤  i≤  k). Your program has to find such a sightseeing route, the length of which is minimal, or to specify that it is not possible, because there is no sightseeing route in the town.

Input

Input contains  T tests (1 ≤  T ≤ 5). The first line of each test contains two integers: the number of crossing points  N and the number of roads  M (3 ≤  N ≤ 100; 3 ≤  M ≤  N · ( N − 1)). Each of the next  M lines describes one road. It contains 3 integers: the number of its first crossing point  a, the number of the second one  b, and the length of the road  l (1 ≤  ab ≤  Na ≠  b; 1 ≤  l ≤ 300 ). Input is ended with a “−1” line.

Output

Each line of output is an answer. It contains either a string “No solution.” in case there isn't any sightseeing route, or it contains the numbers of all crossing points on the shortest sightseeing route in the order how to pass them (i.e. the numbers  x 1 to  xk from our definition of a sightseeing route), separated by single spaces. If there are multiple sightseeing routes of the minimal length, you can output any one of them.

Sample

input output
5 7
1 4 1
1 3 300
3 1 10
1 2 16
2 3 100
2 5 15
5 3 20
4 3
1 2 10
1 3 20
1 4 30
-1
1 3 5 2
No solution.
Problem Source: Central European Olympiad in Informatics 1999


思路:

题意给了一张无向图,求的是这个图的最小环(就是从某个点出发再走回它自己的最短路),并且把路径打印出来。

所以我们求出一个最短路+次短路的和就是所求的路径.我们以环权值最小为标准(最短路权值+次短路权值),记录从i~j的路径以及能松弛i和j点的k中代价最小的那个,一直更新路径,如果遇见更短的路径那么就放弃之前记录的重新记录.floyd是按照结点的顺序更新最短路的,所以我们在更新最短路之前先找到一个连接点k,当前的点k肯定不存在于已存在的最短路dis[i][j]的路径上,因为我们还没用这个k去更新最短路,这样一个环就找到了


map[]来存储原图

dis[]来存储松弛后的图

path[]记录路径

vis[][]标记两个点之间经过哪个点中转过

ans来存储当前最小的环的值,如果遇到更小的,那么就重新记录路径

代码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <string>
#include <iostream>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
#define N 110
#define inf 9999999
#define ll long long
using namespace std;
int n,m,ans,cnt;
int map[N][N],dis[N][N];
int vis[N][N],path[N];
void init()
{for(int i=1; i<=n; i++)for(int j=1; j<=n; j++){dis[i][j]=inf;vis[i][j]=0;}
}
void record(int i,int j)//递归记录路径
{if(vis[i][j]){record(i,vis[i][j]);record(vis[i][j],j);}elsepath[cnt++]=j;
}
void floyd()
{ans=inf;for(int k=1; k<=n; k++){//找出最小环并且记录路径for(int i=1; i<k; i++)for(int j=i+1; j<k; j++)if(ans>dis[i][j]+map[i][k]+map[k][j])//如果最短路加上次短路权值可以成环,就记录{ans=dis[i][j]+map[i][k]+map[k][j];cnt=0;path[cnt++]=i;record(i,j);//回溯记录路径path[cnt++]=k;}//正常的folydfor(int i=1; i<=n; i++)for(int j=1; j<=n; j++)if(dis[i][j]>dis[i][k]+dis[k][j]){dis[i][j]=dis[i][k]+dis[k][j];vis[i][j]=k;}}
}
int main()
{int u,v,w;while(~scanf("%d",&n)&&n!=-1){scanf("%d",&m);init();for(int i=1; i<=m; i++){scanf("%d%d%d",&u,&v,&w);if(w<dis[u][v])dis[u][v]=dis[v][u]=w;}for(int i=1; i<=n; i++)for(int j=1; j<=n; j++)map[i][j]=dis[i][j];floyd();if(ans==inf)puts("No solution.");else{printf("%d",path[0]);for(int i=1; i<cnt; i++)printf(" %d",path[i]);puts("");}}return 0;
}



这篇关于URAL1004 Sightseeing Trip(Folyd求最小环,打印路径)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/152342

相关文章

Linux修改pip和conda缓存路径的几种方法

《Linux修改pip和conda缓存路径的几种方法》在Python生态中,pip和conda是两种常见的软件包管理工具,它们在安装、更新和卸载软件包时都会使用缓存来提高效率,适当地修改它们的缓存路径... 目录一、pip 和 conda 的缓存机制1. pip 的缓存机制默认缓存路径2. conda 的缓

Windows系统下如何查找JDK的安装路径

《Windows系统下如何查找JDK的安装路径》:本文主要介绍Windows系统下如何查找JDK的安装路径,文中介绍了三种方法,分别是通过命令行检查、使用verbose选项查找jre目录、以及查看... 目录一、确认是否安装了JDK二、查找路径三、另外一种方式如果很久之前安装了JDK,或者在别人的电脑上,想

Python中Windows和macOS文件路径格式不一致的解决方法

《Python中Windows和macOS文件路径格式不一致的解决方法》在Python中,Windows和macOS的文件路径字符串格式不一致主要体现在路径分隔符上,这种差异可能导致跨平台代码在处理文... 目录方法 1:使用 os.path 模块方法 2:使用 pathlib 模块(推荐)方法 3:统一使

一文教你解决Python不支持中文路径的问题

《一文教你解决Python不支持中文路径的问题》Python是一种广泛使用的高级编程语言,然而在处理包含中文字符的文件路径时,Python有时会表现出一些不友好的行为,下面小编就来为大家介绍一下具体的... 目录问题背景解决方案1. 设置正确的文件编码2. 使用pathlib模块3. 转换路径为Unicod

MySQL9.0默认路径安装下重置root密码

《MySQL9.0默认路径安装下重置root密码》本文主要介绍了MySQL9.0默认路径安装下重置root密码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录问题描述环境描述解决方法正常模式下修改密码报错原因问题描述mysqlChina编程采用默认安装路径,

python获取当前文件和目录路径的方法详解

《python获取当前文件和目录路径的方法详解》:本文主要介绍Python中获取当前文件路径和目录的方法,包括使用__file__关键字、os.path.abspath、os.path.realp... 目录1、获取当前文件路径2、获取当前文件所在目录3、os.path.abspath和os.path.re

hdu2544(单源最短路径)

模板题: //题意:求1到n的最短路径,模板题#include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#i

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

poj 1287 Networking(prim or kruscal最小生成树)

题意给你点与点间距离,求最小生成树。 注意点是,两点之间可能有不同的路,输入的时候选择最小的,和之前有道最短路WA的题目类似。 prim代码: #include<stdio.h>const int MaxN = 51;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int P;int prim(){bool vis[MaxN];

poj 2349 Arctic Network uva 10369(prim or kruscal最小生成树)

题目很麻烦,因为不熟悉最小生成树的算法调试了好久。 感觉网上的题目解释都没说得很清楚,不适合新手。自己写一个。 题意:给你点的坐标,然后两点间可以有两种方式来通信:第一种是卫星通信,第二种是无线电通信。 卫星通信:任何两个有卫星频道的点间都可以直接建立连接,与点间的距离无关; 无线电通信:两个点之间的距离不能超过D,无线电收发器的功率越大,D越大,越昂贵。 计算无线电收发器D