STL+Floyd【p1690】贪婪的Copy

Description

Copy从卢牛那里听说在一片叫yz的神的领域埋藏着不少宝藏,于是Copy来到了这个被划分为个区域的神地。卢牛告诉了Copy这里共有个宝藏,分别放在第Pi个(1<=Pi<=N)区域。Copy还得知了每个区域之间的距离。现在Copy从1号区域出发,要获得所有的宝藏并到n号区域离开。Copy很懒,只好来找你为他寻找一条合适的线路,使得他走过的距离最短。

Input

第一行一个正整数N(1<=N<=100)

接下来一个N*N的矩阵,第i+1行第j列的数字表示区域i,j之间的距离。每个距离用空格隔开,距离保证i,j<=1000。请注意的i to j距离并不一定等于j to i的距离。

第N+2行一个整数P(0<=P<=10)。

第N+3行共P个用空格隔开的整数,表示有宝藏的区域编号。

Output

一个整数,为Copy获得全部宝藏需要的最短距离。数据保证答案小于等于maxlongint

(nleq 100) emm,(Floyd)水题.

然后看到宝藏最多会有10个.直接枚举全排列即可.

(STL)打法吼啊,(next_permutation)枚举全排列即可 qwq.

不要忘记加上从(1)到第一个有宝藏位置的地方的距离和从最后一个宝藏到(n)的距离

代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cctype>
#define R register
using namespace std;
inline void in(int &x)
{
	int f=1;x=0;char s=getchar();
	while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
	while(isdigit(s)){x=x*10+s-'0';s=getchar();}
	x*=f;
}
int n,m,dis[108][108],pos[12];
int sum,ans;
int main()
{
	in(n);
	for(R int i=1;i<=n;i++)
		for(R int j=1;j<=n;j++)
			if(i!=j)dis[i][j]=214748364;
	for(R int i=1;i<=n;i++)
		for(R int j=1;j<=n;j++)
			in(dis[i][j]);
	for(R int k=1;k<=n;k++)
		for(R int i=1;i<=n;i++)
			for(R int j=1;j<=n;j++)
				dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
	in(m);
	for(R int i=1;i<=m;i++)
		in(pos[i]);
	sort(pos+1,pos+m+1);
	ans=dis[1][pos[1]]+dis[pos[m]][n];
	for(R int i=1;i<m;i++)
		ans+=dis[pos[i]][pos[i+1]];
	while(next_permutation(pos+1,pos+m+1))
	{
		sum=dis[1][pos[1]]+dis[pos[m]][n];
		for(R int i=1;i<m;i++)
			sum+=dis[pos[i]][pos[i+1]];
		ans=min(ans,sum);
	}
	printf("%d",ans);
}
原文地址:https://www.cnblogs.com/-guz/p/9784225.html