# L2-001. Emergency rescue

time limit
200 ms
Memory limit
65536 kB
Code length limit
8000 B
Problem determination procedure
Standard
author
Chen Yue

As the head of a city's emergency rescue team, you have a special national map. There are many scattered cities and some fast roads connecting them on the map. The number of rescue teams in each city and the length of each fast track connecting the two cities are marked on the map. When other cities have emergency call to you, your task is to lead your rescue team to catch up with the past as soon as possible, and at the same time, gather as many rescue teams as possible along the way.

Input format:

Input the first line to give four positive integers N, m, S and D, where N (2 < = N < = 500) is the number of cities, and by the way, assume that the number of cities is 0~(N-1); m is the number of expressways; S is the number of cities of departure; D is the number of cities of destination. The second line gives N positive integers, where the number i is the number of rescue teams in the city i, separated by spaces. In the following M lines, each line gives the information of an expressway, which is the length of city 1, city 2 and expressway, separated by spaces, and the numbers are integers and no more than 500. The input ensures that the rescue is feasible and the optimal solution is unique.

Output format:

The first line outputs the number of different shortest paths and the maximum number of rescue teams that can be called. The second line outputs the city number that passes in the path from S to D. The numbers are separated by spaces. The first and last output cannot have extra spaces.

Input example:
```4 5 0 3
20 30 40 10
0 1 1
1 3 2
0 3 3
0 2 2
2 3 2
```
Output example:
```2 60
0 1 3```
`Title Link`
`dijskta+dfs`
```#include<iostream>
#include<cstdio>
#include<cstring>
#define INF 999999
int n, m, s, d, vis, l, dis, p, sum, ans;
void dfs(int length, int people, int dd)
{
int i;
if(dd == s)
return;
for(i = 0 ; i < n ; i++)
{
if(length - l[dd][i] == dis[i] && people - p[dd] == sum[i])
{
dfs(dis[i], sum[i], i);
printf("%d ", i);
break;
}
}
}
void dij()
{
int i, j, k, min;
vis[s] = 1;
sum[s] = p[s];
ans[s] = 1;
for(i = 0 ; i < n ; i++)
{
dis[i] = l[s][i];
if(s != i && l[s][i] != INF)
{
sum[i] = p[i] + p[s];
ans[i] = 1;//
}
}
for(i = 0 ; i < n-1 ; i++)
{
min = INF;
for(j = 0 ; j < n ; j++)
{
if(!vis[j] && min > dis[j])
{
min = dis[j];
k = j;
}
}
vis[k] = 1;
for(j = 0 ; j < n; j++)
{
if(!vis[j])
{
if(dis[j] > dis[k] + l[k][j])
{
dis[j] = dis[k] + l[k][j];
sum[j] = sum[k] + p[j];
ans[j] = ans[k];//
}
else if(dis[j] == dis[k] + l[k][j])
{
ans[j] += ans[k];//
if(sum[j] < sum[k] + p[j])
{
sum[j] = sum[k] + p[j];
}
}
}
}
}
}
int main()
{
int i, j, x, y, ll;
scanf("%d %d %d %d", &n, &m, &s, &d);
for(i = 0 ; i < n ; i++)
for(j = 0 ; j < n ; j++)
{
l[i][j] = INF;
}
for(i = 0 ; i < n; i++)
{
scanf("%d", &p[i]);
}
for(i = 0 ; i < m ; i++)
{
scanf("%d %d %d", &x, &y, &ll);
l[x][y] = l[y][x] = ll;
}
if(n == 1)
{
printf("1 %d\n1", p);
return 0;
}
dij();
printf("%d %d\n", ans[d], sum[d]);
printf("%d ", s);
dfs(dis[d], sum[d], d);
printf("%d", d);
return 0;
}
```

Posted by buddymoore on Sat, 02 May 2020 12:10:10 -0700