[SSL] 1763 sightseeing tour (minimum loop problem)

[SSL] 1763 sightseeing tour

Time Limit:2000MS Memory Limit:65536K

Description

There is a tourist agency in the town of Adelton in Zanzibar. They decided to provide guests with the services of visiting the town in addition to providing many other attractions. In order to profit as much as possible from the attraction services provided, the tourism agency took a shrewd decision: to find the shortest route between the same starting point and ending point.
Your task is to write a program to find a similar route. In this town, there are N intersections (numbered 1 to N), there can be multiple road connections between two intersections, and there are M roads (numbered 1 to M). But no road starts from the same intersection and returns to the same intersection. Each sightseeing route is composed of some roads, the serial numbers of these roads are: y1, …, yk, and k>2. Road No. yi (1<=i<=k-1) connects No. xi intersection and No. x[i+1] intersection; Road No. yk connects No. xk intersection and No. x Crossroads number [k+1]. And all these x1,...,xk respectively represent the serial numbers of different intersections. The sum of the length of all roads on a certain sightseeing route is the total length of this sightseeing route. In other words, the sum of L(y1)+L(y2)+...+L(yk), L(yi) is the length of the No. yi sightseeing route. Your program must find a similar route: the length must be the smallest, or that there is no such sightseeing route in this town.

Input

The first row of each group of data contains two positive integers: the number of intersections N (N<=100), and the other is the number of roads M (M<10000). Each next line describes a road: each line has three positive integers: the number of the two intersections that the road connects, and the length of the road (a positive integer less than 500).

Output

Each line of output is an answer. If this sightseeing route does not exist, display "No solution"; or output the length of the shortest route.

Sample Input

Example 1
5 7
1 4 1
1 3 300
3 1 10
1 2 16
2 3 100
2 5 15
5 3 20
Example 2
4 3
1 2 10
1 3 20
1 4 30

Sample Output

Example 1
61
Example 2
No solution

Hint

Ideas

The smallest ring refers to finding a ring in a graph so that the sum of the weights of the edges on the ring is the smallest. While Floyed, the smallest ring can be calculated by the way.
  Remember the shortest path between two points is dis[i][j], g[i][j] is the weight of edge <i,j>.
  for (k = 1; k <= n; k++)
    {     for (i = 1; i <= k-1; i++) for (j = i+1; j <= k-1; j++)      answer = min( answer,dis[i][j]+g[j][k]+g[k][i]);     for (i = 1; i <= n; i++) for (j = 1; j <= n ; j++)       dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]); }   answer is the smallest ring in this picture.   The largest node in a ring is k (the largest number), and the two points connected to it are i, j. The shortest length of this ring is g[i][k]+g[k][j]+(i In the path to j, all node numbers are less than the shortest path length of k).   According to Floyed's principle, after the outermost loop is done k-1 times, dis[i][j] represents the shortest path from i to j where all node numbers are less than k.   In summary, the algorithm must be able to find the smallest ring in the graph.










Code

#include<iostream>
#include<cstdio> 
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
long long n,m,g[110][110],dis[110][110],ans;
void input()
{
    
    
	long long i,j,x,y,z;
	scanf("%lld%lld",&n,&m);
	for(i=0;i<=n;g[i][i]=dis[i][i]=0,i++)
	{
    
    
		for(j=0;j<=n;j++)
			g[i][j]=dis[i][j]=1000000000;
	}
	for(i=1;i<=m;i++)
	{
    
    
		scanf("%lld%lld%lld",&x,&y,&z);
		g[x][y]=g[y][x]=min(g[x][y],z);
		dis[x][y]=dis[y][x]=min(dis[x][y],z);
	}
	ans=1000000000;
	return;
}
void floyd()
{
    
    
	long long k,i,j;
	for(k=1;k<=n;k++)
	{
    
    
		for(i=1;i<k;i++)
			for(j=i+1;j<k;j++)
				ans=min(ans,dis[i][j]+g[i][k]+g[k][j]);//求最小环 
		for(i=1;i<=n;i++)
			for(j=1;j<=n;j++)
				dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);//松弛 
	}
	return;
}
int main()
{
    
    
	input();
	floyd();
	if(ans==1000000000)
		printf("No solution");
	else
		printf("%lld",ans);
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_46975572/article/details/112392208