[Swust OJ 842]--实验室和食堂(最短路,Dijkstra算法)
题目链接:http://acm.swust.edu.cn/problem/842/
Time limit(ms): 1000 Memory limit(kb): 10000
Description
2012新的暑期集训开始了,一切都还相当不错,但是有一个问题成为了同学们的难题,那就是从实验室到食堂时,天气是非常的炎热,以至于大家都尽量避免从没有遮阴的地方走过,但是某些路径又不得不从没有遮阴的地方走过,所以现在难题出来了,给予你一些单向路段,让你找出从实验室到食堂,晒太阳最少的路径长度,以及该条路径的总长度。如果存在多条最少晒太阳的路径,则总长度要求最短。
输入n和m,表明是有n<=1000个转折点,m条路径,然后输入m(m<=100000)条路径,每一条路径包括4个数据,s,e,dis1 , dis2,分别表示该条路径的起点,
终点,路径总长度,以及没有遮阴路径的长度(dis1>=dis2);
结果保证小于2^31
Input
输出两个值,第一个值是没有遮阴路径的最小总长度,第二个是该条路径的总长度,如果没有遮阴路径的最小总长度相等,
Output
输出二者中总路径长度最小的那条路径的长度值。
Sample Input
3 4
1 2 10 2
1 2 11 1
2 3 5 2
2 3 7 1
4 4
1 2 10 2
2 4 10 3
1 3 5 3
3 4 16 2
|
Sample Output
2 18
5 20
|
解题思路:起点为1,终点为n,两个数组,一个存贮路径长度,一个是最少晒到阳光的长度,然后用Dijkstra算法就是~~~~
代码如下:
1 #include <iostream> 2 #include <cstring> 3 const int maxn = 1005; 4 const int inf = 0x3f3f3f3f; 5 using namespace std; 6 7 int diaA[maxn][maxn], disB[maxn][maxn], n, m, x, y, d1, d2; 8 9 void init() 10 { 11 for (int i = 1; i <= n; i++){ 12 for (int j = i; j <= n; j++) 13 diaA[i][j] = diaA[j][i] = disB[i][j] = disB[j][i] = inf; 14 } 15 } 16 void Dijkstra(){ 17 int dis[maxn], pay[maxn], vis[maxn], i, j, k; 18 memset(vis, 0, sizeof(vis)); 19 for (i = 1; i <= n; i++){ 20 dis[i] = diaA[1][i]; 21 pay[i] = disB[1][i]; 22 } 23 vis[1] = 1; 24 for (i = 1; i <= n; i++){ 25 int min = inf; 26 for (j = 1; j <= n; j++){ 27 if (!vis[j] && pay[j] < min){ 28 min = pay[j]; 29 k = j; 30 } 31 } 32 vis[k] = 1; 33 for (j = 1; j <= n; j++){ 34 if (!vis[j]){ 35 if (pay[k] + disB[k][j]<pay[j] || pay[k] + disB[k][j] == pay[j] && dis[j]>dis[k] + diaA[k][j]){ 36 pay[j] = pay[k] + disB[k][j]; 37 dis[j] = dis[k] + diaA[k][j]; 38 } 39 } 40 } 41 } 42 cout << pay[n] << ' ' << dis[n] << endl; 43 } 44 45 int main(){ 46 while (cin >> n >> m){ 47 init(); 48 for (int i = 0; i < m; i++){ 49 cin >> x >> y >> d1 >> d2; 50 if (d2 < disB[x][y] || d2 == disB[x][y] && d1 < diaA[x][y]){ 51 diaA[x][y] = d1; 52 disB[x][y] = d2; 53 } 54 } 55 Dijkstra(); 56 } 57 return 0; 58 }
如果这是你所爱的,就不要让自己后悔~~~