【问题简述】
给出N个城市和M条带权无向边,求从1到N在必须经过给定的T个城市的前提下的最短路长度。
【输入】
第一行:n,m,t,表示城市数,道路数,必须经过的城市数
第二行:t个整数,表示必经的城市
接下来m行,每行3个整数,前两个表示城市,第三个数是这两个城市间的直达时间
【输出】
一个数,最短时间
【数据范围】
n<=200,m<=20000,直达时间<=1000000
【时限】
5s
【样例输入】
5 10 2
2 3
1 2 5
1 3 45
1 4 61
1 5 81
2 3 9
2 4 91
2 5 4
3 4 74
3 5 42
4 5 61
【样例输出】
27
【问题分析】
floyd(或t+1次单源最短路径)+搜索排列
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAXN 210
#define oo ((LL)1000000*20000+10)
using namespace std;
typedef long long LL;
LL MIN(LL x,LL y){ return x g[MAXN],w[MAXN];
LL d[MAXN][MAXN];
void floyd()
{
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++)
d[i][j]=i==j?0:oo;
for(int i=1;i<=N;i++){
for(int k=0;kT){
ans=MIN(ans,len+d[j][N]);
return;
}
for(int x=1;x<=T;x++)if(vis[x]==0){
vis[x]=1;
LL t=len+d[j][must[x]];
run(i+1,must[x],t);
vis[x]=0;
}
}
int main()
{
cin>>N>>M>>T;
for(int i=1;i<=T;i++) scanf("%d",must+i);
for(int i=1;i<=M;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
g[a].push_back(b); w[a].push_back(c);
g[b].push_back(a); w[b].push_back(c);
}
floyd();
ans=oo;
memset(vis,0,sizeof(vis));
run(1,1,0);
cout<