【题目描述】
重庆城里有 n 个车站,m 条双向公路连接其中的某些车站。每两个车站最多用一条公路连接,从任何一个车站出发都可以经过一条或者多条公路到达其他车站,但不同的路径需要花费的时间可能不同。在一条路径上花费的时间等于路径上所有公路需要的时间之和。
佳佳的家在车站 111,他有五个亲戚,分别住在车站 a,b,c,d,e。过年了,他需要从自己的家出发,拜访每个亲戚(顺序任意),给他们送去节日的祝福。怎样走,才需要最少的时间?
【输入描述】
第一行:n,m 为车站数目和公路的数目。
第二行:a,b,c,d,e 为五个亲戚所在车站编号。
以下 m 行,每行三个整数 x,y,t ,为公路连接的两个车站编号和时间。
【输出描述】
输出仅一行,包含一个整数 T,为最少的总时间。
【样例输入】
6 6
2 3 4 5 6
1 2 8
2 3 3
3 4 4
4 5 5
5 6 2
1 6 7
【样例输出】
21
【思路】
最短路径水题…
从起点和每个亲戚家出发走一次最短路径,然后再通过深度优先搜索枚举每种走法的时间,取最小的那个。
代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<queue>
#include<algorithm>
#define re register
using namespace std;
int n,m,k,a[6];
struct node{
int u,v,w;
}e[200001];
int f[50001];
int nxp[200001];
int cnt=0;
void add(int u,int v,int w)
{
e[++cnt].u=u;
e[cnt].v=v;
e[cnt].w=w;
nxp[cnt]=f[u];
f[u]=cnt;
}
int d[50001][6];
bool vis[100001];
inline void spfa(int s,int t)
{
queue<int>q;
d[s][t]=0;
memset(vis,0,sizeof(vis));
q.push(s);
vis[s]=1;
while(!q.empty())
{
int u=q.front();q.pop();vis[u]=0;
for(int re i=f[u];i;i=nxp[i])
{
int v=e[i].v;
if(d[v][t]>d[u][t]+e[i].w)
{
d[v][t]=d[u][t]+e[i].w;
if(!vis[v])
{
vis[v]=1;
q.push(v);
}
}
}
}
}
int ans=0x7f7f7f7f;
inline void dfs(int u,int num,int y,int t)
{
if(num==6)
{
ans=min(ans,y);
return;
}
for(int re i=1;i<=5;i++)
{
if(!vis[a[i]])
{
vis[a[i]]=1;
dfs(a[i],num+1,y+d[a[i]][t],i);
vis[a[i]]=0;
}
}
}
int main()
{
memset(d,127/3,sizeof(d));
scanf("%d%d",&n,&m);
a[0]=1;
for(int re i=1;i<=5;i++)
scanf("%d",&a[i]);
for(int re i=1;i<=m;i++)
{
int u,v,r;
scanf("%d%d%d",&u,&v,&r);
add(u,v,r);add(v,u,r);
}
for(int re i=0;i<=5;i++)
spfa(a[i],i);
vis[1]=1;dfs(a[0],1,0,0);
cout<<ans;
}