一个图上,有M条边,Z个出发点,Y个终止点。求一条最短路,其中起点是Z中的任意一点,终点是Y中任意一点。
Input 输入数据有多组,输入直到文件结束。
每组的第一行是三个整数M,Z,Y
接着有M行,每行有三个整数a,b,w,表示a,b之间存在一条长度为w的边 (1=<(a,b)<=1000,w原题干未给范围c++
int够用),可能存在重边,边为双向边。接着的第M+1行有Z个数,表示起点标号
接着的第M+2行有Y个数,表示终点标号
Output 每组数据,输出一个整数占一行表示最短路的长度
Sample Input
6 2 3
1 3 5
1 4 7
2 8 12
3 8 4
4 9 12
9 10 2
1 2
8 9 10
Sample Output
9
题意:给我们一个有多个出发点、多个终点的图,从任意一个出发点到任意一个终点的最短路是多少
思路:类似于网络流,分别增加 相应的超级源点、和汇点,这两个点到相应的出发点、终点的边的权均为0,在跑一下 Dijkstra(更优)或者Spfa
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<map>
#include<string>
#include<stack>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define INF 1e9
const int Len = 5000;
struct Edge
{
int v, w, next;
} edge[Len];
int k = 0;
int head[Len];
void Add(int u, int v, int w)
{
edge[++ k] = (Edge){ v, w, head[u] };
head[u] = k;
}
int Spfa(int s, int e)
{
int use[Len], dis[Len];
for(int i = s; i <= e; i ++)
use[i] = 0, dis[i] = INF;
dis[s] = 0;
queue<int> q;
q.push(s);
int u, v, w;
while(! q.empty())
{
u = q.front(); q.pop();
use[u] = 0;
for(int i = head[u]; i; i = edge[i].next)
{
v = edge[i].v;
w = edge[i].w;
if(dis[v] > dis[u] + w)
{
dis[v] = dis[u] + w;
if(! use[v])
{
q.push(v);
use[v] = 1;
}
}
}
}
return dis[e];
}
void init()
{
k = 0;
memset(head, 0, sizeof(head));
}
int main()
{
/* freopen("A.txt","r",stdin); */
/* freopen("Ans.txt","w",stdout); */
int m,z,y;
while(~ scanf("%d %d %d", &m, &z, &y))
{
init();
int u, v, w;
for(int i = 1; i <= m; i ++)
{
scanf("%d %d %d", &u, &v, &w);
Add(u, v, w);
Add(v, u, w);
}
int s = 0, e = 1005;
int ver;
for(int i = 1; i <= z; i ++)
scanf("%d", &ver), Add(s, ver, 0);
for(int i = 1; i <= y; i ++)
scanf("%d", &ver), Add(ver, e, 0);
printf("%d\n", Spfa(s, e));
}
return 0;
}
# H - H HDU - 2066 (多起点、多终点问题)
原文:https://www.cnblogs.com/lql-nyist/p/12619057.html