求最短路,以草儿所在的地方设为0,当做源点,草儿临近的城市到草儿的距离设为0
这里有一点要注意:并不是1~N的城市都出会出现,所以我用city数组来存储出现过的城市编号,
如city[i]=1表示 i 出现在数据里,这样就减少不必要的遍历。
#include <iostream> #include <algorithm> #include <string.h> #include <stdio.h> #include <string> #include <vector> #include <queue> using namespace std; const int maxn=0x3f3f3f3f; int road[1010][1010];//road[i][j]表示i与j的距离(这里指进过该条路的时间) int dis[1010];//dis[i]表示i点到源点1的最短路径大小 int vis[1010];//vis[i]=1表示节点i已经求过到源点的单源最短路径 int city[1010];//city[i]=1表示存在该城市,即该城市在数据里出现过 vector<int> link[1010];//link[i]表示i与哪些点连接 vector<int> goal;//存储喜欢去的城市。 int T,S,D; int a,b,c,t; struct Node{ int u,dis; bool operator<(const Node tmp) const{ return dis>tmp.dis; //优先级序列默认的是最先取出的是“最大的”。 } //如果按从小到大排,则优先级队列取最大的。 //如果从大到小排,则优先级队列取最小的。 }; void dijkstra(){ priority_queue<Node> q; Node tmp,a; memset(dis,maxn,sizeof(dis)); memset(vis,0,sizeof(vis)); dis[0]=0; city[0]=1; a.u=0; a.dis=0; q.push(a); while(!q.empty()){ tmp=q.top(); q.pop(); int idx=tmp.u; vis[idx]=1; for(int k=0; k<link[idx].size(); k++) { int v=link[idx][k]; if(v!=idx && !vis[v]) { if(dis[idx]+road[idx][v]<dis[v]) { dis[v]=dis[idx]+road[idx][v]; a.u=v; a.dis=dis[v]; q.push(a); } } } } } int main() { while(scanf("%d%d%d",&T,&S,&D)!=EOF) { //U.clear(); memset(road,0,sizeof(road)); memset(city,0,sizeof(city)); goal.clear(); for(int i=0; i<1010; i++) link[i].clear(); for(int i=0; i<T; i++) { scanf("%d%d%d",&a,&b,&c); if(!road[a][b]) { city[a]=1; city[b]=1; road[a][b]=c; road[b][a]=c; link[a].push_back(b); link[b].push_back(a); } else if(c<road[a][b]) { road[a][b]=c; road[b][a]=c; } } for(int i=0; i<S; i++) { scanf("%d",&t); link[0].push_back(t); } for(int i=0; i<D; i++) { scanf("%d",&t); goal.push_back(t); } dijkstra(); int mintime=maxn; for(int i=0; i<D; i++) { int v=goal[i]; mintime=min(mintime,dis[v]); } printf("%d ",mintime); } return 0; }