简要分析:
- 本题要求经过一定的点的最短路
- 易得,从 i 点出发,经过 k 点 ,到达 j 点的最短路, 一定是从 i 到 k 的最短路加上从 k 到 j 的最短路
- 证明 :假设:从 i 点出发,经过 k 点 ,到达 j 点的最短路,不是从 i 到 k 的最短路加上从 k 到 j 的最短路
- 则应存在 路径 E1(i->k)+E2(k->j)<E1min+E2min 易证得假设不成立
- 枚举 从每个亲戚家出发到达其它车站所需时间
- 再枚举每种路径所需时间
- 时间复杂度(5*M log M+5^5) 可以接受
注意事项
- 本题是无向图,注意建图和建边
- 注意每次dijkstra都要重新预处理
具体代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int inf=2147483637,Max_N=50010,Max_M=100010;
typedef pair<int,int>node;
struct Edge
{
int dis,to,next;
} E[Max_M*2];//注意是无向边
int Head[Max_N],Dis[6][Max_N],num_Edge,vis[Max_N];
inline int Read(void)//快读
{
char ch=0;
int w=0,x=0;
while(!isdigit(ch)) w|=ch=='-',ch=getchar();
while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
return w?-x:x;
}
inline void Add_Edge(int from,int to,int dis)//建边
{
E[++num_Edge].dis =dis;
E[num_Edge].to =to;
E[num_Edge].next =Head[from];
Head[from]=num_Edge;
}
int N,M,T[6],S,Ans=inf;
inline void Dijkstra(int num)//求从T[num]点出发到达每点的最短路
{
priority_queue <node,vector<node>,greater<node> >Q;
for(int i=1; i<=N; ++i) Dis[num][i]=(i==S?0:inf),vis[i]=0;
Q.push(make_pair(0,S)) ;
while(!Q.empty() )
{
int u=Q.top() .second;
Q.pop() ;
if(vis[u])continue;
else vis[u]=1;
for(int i=Head[u]; i; i=E[i].next )
{
int v=E[i].to ;
if(Dis[num][v]>Dis[num][u]+E[i].dis )
{
Dis[num][v]=Dis[num][u]+E[i].dis ;
if(!vis[v]) Q.push(make_pair(Dis[num][v],v)) ;
}
}
}
}
int main(void)
{
N=Read(),M=Read();
for(int i=1; i<=5; ++i) T[i]=Read();
for(int i=1; i<=M; ++i)
{
int u=Read(),v=Read(),d=Read();
Add_Edge(u,v,d);//注意是无向边
Add_Edge(v,u,d);
}
T[0]=1;
for(int i=0; i<=5; ++i)
{
S=T[i];
Dijkstra(i);
}
memset(vis,0,sizeof(vis));
for(int t1=1; t1<=5; ++t1)//枚举路径
{
vis[t1]=1;
for(int t2=1; t2<=5; ++t2)
{
if(!vis[t2])
{
vis[t2]=1;
for(int t3=1; t3<=5; ++t3)
{
if(!vis[t3])
{
vis[t3]=1;
for(int t4=1; t4<=5; ++t4)
{
if(!vis[t4])
{
vis[t4]=1;
for(int t5=1; t5<=5; ++t5)
{
if(!vis[t5])
{
Ans=min(Ans,Dis[0][T[t1]]+Dis[t1][T[t2]]+Dis[t2][T[t3]]+Dis[t3][T[t4]]+Dis[t4][T[t5]]);
}
}
vis[t4]=0;
}
}
vis[t3]=0;
}
}
vis[t2]=0;
}
}
vis[t1]=0;
}
printf("%d
",Ans);
return 0;
}