最短路,只不过有多个开始点和结束点,选一条从任意开始点到任意结束点最短的路。
再额外建立一个虚拟开始点和虚拟结束点即可。
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
const int INF = 1e9;
const int MAXN = 1002;
int T, S, D;
int g[MAXN][MAXN];
int dis[MAXN];
bool vis[MAXN];
bool exist[MAXN];
void dijkstra(int s)
{
dis[s] = 0;
int counter = 0;
for (int i = 0; i < MAXN; i++)
if (exist[i]) counter++;
for (int i = 0; i < counter; i++) // exist主要就是为了减少外循环的次数,有多少点 循环多少次就够了
{
int u = -1, mind = INF;
for (int j = 0; j <= 1001; j++)
{
if (!vis[j] && exist[j] && dis[j] < mind) // 这处的exist其实没什么用
{
mind = dis[j];
u = j;
}
}
vis[u] = 1;
for (int j = 0; j <= 1001; j++)
{
if (!vis[j] && exist[j] && g[u][j] != -1) // 这处的exist其实没什么用
{
if (dis[u] + g[u][j] < dis[j])
dis[j] = dis[u] + g[u][j];
}
}
}
}
int main()
{
int a, b, c;
for (; ~scanf("%d%d%d", &T, &S, &D);)
{
memset(g, -1, sizeof g);
memset(vis, 0, sizeof vis);
fill(dis, dis + MAXN, INF);
memset(exist, 0, sizeof exist);
for (; T--;)
{
scanf("%d%d%d", &a, &b, &c);
exist[a] = true;
exist[b] = true;
if (g[a][b] == -1) g[a][b] = g[b][a] = c;
else g[a][b] = g[b][a] = min(g[a][b], c);
}
for (; S--;)
{
scanf("%d", &a);
g[0][a] = g[a][0] = 0;
exist[0] = true;
}
for (; D--;)
{
scanf("%d", &a);
g[1001][a] = g[a][1001] = 0;
exist[1001] = true;
}
dijkstra(0);
printf("%d\n", dis[1001]);
}
return 0;
}