题意:一个人,要坐公交去上班。一直有n各站点,m条路线,已知他可以从w各站点出发坐车,求到达目的地s所用的最少时间。如不能到达,则输出-1。
解析:Dijkstra算法,不过直接使用w次Dijkstra,会超时的。下面有两个思路:
1.将这个人的位置设为站点0,然后将站点0和那w个出发点连接在一起,相当于从他家到这些站点的时间为0。然后再使用Dijkstra,输出d[s]即可。
2.利用反向图,因为可以有多个起点,但是只有一个终点,所以反向图的话,相当于只有一个起点,好多个终点了,这样只要使用一次Dijkstra,然后输出w个起点中的最小值即可。
PS:一定要注意公交线路是单向的,一定要建成有向图!!!
AC代码:
思路一
#include
#include
#include
#include
using namespace std;
#define INF 1e7 + 2
const int maxn = 1000 + 5;
int n, m;
int w[maxn][maxn], d[maxn], v[maxn];
void dijkstra(int s){
memset(v, 0, sizeof(v));
for(int i=0; i<=n; i++) d[i] = w[s][i];
d[s] = 0;
v[s] = 1;
for(int i=0; i<=n; i++){
int x, m = INF;
for(int y=0; y<=n; y++)
if(!v[y] && d[y] <= m) m = d[x = y];
if(m == INF) break;
v[x] = 1;
for(int y=0; y<=n; y++) d[y] = min(d[y], d[x] + w[x][y]);
}
}
int main(){
#ifdef sxk
freopen("in.txt", "r", stdin);
#endif //sxk
int x, y, z, s, t;
while(scanf("%d%d%d", &n, &m, &s)!=EOF){
for(int i=0; i<=n; i++)
for(int j=0; j<=n; j++)
w[i][j] = (i==j ? 0 : INF);
for(int i=0; i
思路二
#include
#include
#include
#include
using namespace std;
#define INF 1e7 + 2
const int maxn = 1000 + 5;
int n, m;
int w[maxn][maxn], d[maxn], v[maxn];
void dijkstra(int s){
memset(v, 0, sizeof(v));
for(int i=0; i<=n; i++) d[i] = w[s][i];
d[s] = 0;
v[s] = 1;
for(int i=0; i<=n; i++){
int x, m = INF;
for(int y=0; y<=n; y++)
if(!v[y] && d[y] <= m) m = d[x = y];
if(m == INF) break;
v[x] = 1;
for(int y=0; y<=n; y++) d[y] = min(d[y], d[x] + w[x][y]);
}
}
int main(){
#ifdef sxk
freopen("in.txt", "r", stdin);
#endif //sxk
int x, y, z, s, t;
while(scanf("%d%d%d", &n, &m, &s)!=EOF){
for(int i=0; i<=n; i++)
for(int j=0; j<=n; j++)
w[i][j] = (i==j ? 0 : INF);
for(int i=0; i