- 原题链接:Here!
- 分析:和草儿家相邻的城市的有S个,草儿想去的地方有D个。所以这个问题起点集合是S{},终点集合是D{}。我们只需要计算出每一个起点到所有终点的最短距离,然后选出其中最小的距离就是答案。
- 注意:输入时会出现重边,需要对重边进行处理。
- CODE:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 1000+10; const int inf = 0x3f3f3f; int G[maxn][maxn]; int vis[maxn]; int dis[maxn]; int T,S,D; // T条路,和草儿家相邻的城市的有S个,草儿想去的地方有D个 void Dijkstra(int s){ //时间复杂度为0(n^2),用于1000点 memset(vis,0,sizeof(vis)); vis[s]=1; for(int i=1;i<=1000;i++) dis[i]=G[s][i]; for(int i=1;i<1000;i++){ int k=-1 , minn=inf; for(int j=1;j<=1000;j++){ if(!vis[j]&&dis[j]<minn){ k=j; minn=dis[j]; } } if(k==-1) return ; vis[k]=1; for(int j=1;j<=1000;j++){ if(!vis[j]&&dis[j]>G[k][j]+dis[k]) dis[j]=G[k][j]+dis[k]; } } } int main(){ while(scanf("%d%d%d",&T,&S,&D)!=EOF){ memset(G,inf,sizeof(G)); for(int i=1;i<=T;i++){ int a,b,time; scanf("%d%d%d",&a,&b,&time); G[a][b]=G[b][a]=min(time,G[a][b]); // 处理重边 } int start[maxn],aim[maxn]; // 起点集和终点集 for(int i=0;i<S;i++) scanf("%d",&start[i]); for(int i=0;i<D;i++) scanf("%d",&aim[i]); int min_len=inf; for(int i=0;i<S;i++){ Dijkstra(start[i]); for(int j=0;j<D;j++) if(min_len>dis[aim[j]]) min_len=dis[ aim[j] ]; memset(dis,0,sizeof(dis)); } printf("%d\n",min_len); } return 0; }