2020 Winter Holiday [gmoj2405] [danger coefficient] [floyed shortest route]

Title description

FJ is on a boat, there are N (1 <= N <= 100) islands on the sea, numbered 1 ... N, now his task is to explore this M () according to a given visit order A_1, A_2, ... A_M 2 <= M <= 10,000) islands, already know the risk coefficient between any two islands, let you find an exploration sequence, as long as your exploration sequence contains the given A_1 ... A_M sequence can be ( It does not have to be continuous) to minimize the total risk factor.

Input

Line 1: Two numbers, N and M
Line 2 ... M + 1: Line i + 1 represents the i-th island in the given sequence A_i
Line M + 2 ... N + M + 1: Each line N Integers, representing the risk factor between islands, must be 0 on the left diagonal.

Output

The output meets the required minimum risk factor

Sample input

3 4
1
2
1
3
0 5 1
5 0 2
1 2 0

Sample output

7

prompt

We can explore in the order of 1, 3, 2, 3, 1, 3, which satisfies the word sequence that stipulates that the sequence is the sequence, and the risk factor is (1,3) + (3,2) + (2,3 ) + (3,1) + (1,3) = 7.

analysis

Since this question is going to go through a sequence, the shortest sum should be the shortest sum of two adjacent points in the sequence.
Therefore, only floyed is used to find the shortest path of all points. Then the cyclic sequence accumulates the shortest path. n 3 no problem.

Code on

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,a[10001],f[101][101],ans;
int main()
{
    freopen("danger.in","r",stdin);
    freopen("danger.out","w",stdout);
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
    	cin>>a[i];
	}
	for(register int i=1;i<=n;i++)
	{
		for(register int j=1;j<=n;j++)
		{
			cin>>f[i][j];
		}
	}
	for(register int k=1;k<=n;k++)
	{
		for(register int i=1;i<=n;i++)
		{
			for(register int j=1;j<=n;j++)
			{
				if(i!=j&&j!=k&&k!=i&&f[i][k]+f[k][j]<f[i][j])
				{
					f[i][j]=f[i][k]+f[k][j];
				}
			}
		}
	}
	for(register int i=1;i<=m-1;i++)
	{
		ans+=f[a[i]][a[i+1]];
	}
	cout<<ans;
    fclose(stdin);
    fclose(stdout);
    return 0;
}

Published 110 original articles · won 100 · visited 8022

Guess you like

Origin blog.csdn.net/dglyr/article/details/104906700