题意:如上图,给出数个可任选的起点和终点,求最短时间。
算法:dijkstra
问题:本题与畅通工程不同,位置的序号不是从0到t-1标好的,所有需要遍历1000次以上,一开始写错了;之后则是因为变量名的问题,自己常用变量名s被题目中相关内容占用了,临时改成了start,却下意识地在部分代码中依旧使用了s,所以不应改变自己常用变量名,而是改变题目的。
思路:设置一个源起点连接数个起点,再设置一个终点连接几个目标点,将其转化为普通问题。
代码:ac
#include<bits/stdc++.h>
using namespace std;
#define inf 0x7fffffff
int Map[1010][1010];
int vis[1010];
int Dist[1010];
int main()
{
int t, s, d;/*路,起始点数目,终点数目*/
int a, b, time;
int Min;
int start, end;/*设0点为起点,1001点为终点*/
int nex;
while (scanf("%d%d%d", &t, &s, &d) != EOF) {
for (int i = 0; i <= 1001; i++) {/*初始化*/
Dist[i] = inf;
vis[i] = 0;
for (int j = 0; j <= 1001; j++)
Map[i][j] = inf;
}
while (t--) {
scanf("%d%d%d", &a, &b, &time);
Map[a][b] = min(Map[a][b], time);
Map[b][a] = Map[a][b];
}
while (s--) {
int o;
scanf("%d", &o);
Map[0][o] = 0;
Map[o][0] = 0;/*让0点与s个初始点相连*/
}
while (d--) {
int p;
scanf("%d", &p);
Map[1001][p] = 0;/*让1001点和d个目标点相连*/
Map[p][1001] = 0;
}
start = 0;
end = 1001;
Dist[start] = 0;
vis[start] = 1;
while (start != end) {
Min = inf;
for (int i = 1; i <= 1001; i++) {
if (Map[start][i] != inf) {
Dist[i] = min(Dist[i], Dist[start] + Map[start][i]);
}
if (Dist[i] < Min&&!vis[i]) {
nex = i;
Min = Dist[i];
}
}
if (Min == inf)break;
start = nex;
vis[start] = 1;
}
if (Dist[end] == inf)printf("-1\n");
else printf("%d\n", Dist[end]);
}
return 0;
}