【最短路+dijkstra+spfa】杭电 hdu 2962 Trucking

来源:互联网 发布:php 字符串位置 编辑:程序博客网 时间:2024/05/16 00:51

 

Spfa 解法 

/* THE PROGRAM IS MADE BY PYY *//*----------------------------------------------------------------------------//Copyright (c) 2011 panyanyany All rights reserved.URL   : http://acm.hdu.edu.cn/showproblem.php?pid=2962Name  : 2962 TruckingDate  : Thursday, January 19, 2012Time Stage : one hourResult: 52763042012-01-19 18:31:14Accepted2962250MS596K2705 BC++pyyTest Data :Review :根据华神指点,特用 spfa 做一次,发现邻接表要比矩阵快很多啊//----------------------------------------------------------------------------*/#include <stdio.h>#include <string.h>#include <vector>#include <queue>using namespace std ;#define INF0x3f3f3f3f#define MAXN1002#define min(x, y)((x) < (y) ? (x) : (y))#define max(x, y)((x) > (y) ? (x) : (y))#define MEM(a, v)memset (a, v, sizeof (a))struct EDGE {int to ;int hei, dis ;};boolused[MAXN] ;intc, r ;intdist[MAXN] ;vector<EDGE>map[MAXN] ;int spfa (const int beg, const int end, const int lim){queue<int>q ;EDGEe ;int i, t ;MEM (dist, INF) ;MEM (used, 0) ;q.push (beg) ;used[beg] = 1 ;dist[beg] = 0 ;while (!q.empty ()){t = q.front () ;q.pop () ;for (i = 0 ; i < map[t].size() ; ++i){e = map[t][i] ;if (e.hei >= lim && dist[t] + e.dis < dist[e.to]){// !used[e.to] 不能写到上面的判断里去。/*5 61 2 7 51 3 4 22 4 -1 102 5 2 43 4 10 14 5 8 51 5 4在这个例子中,4 先被 3 入队,used[4] = 1,当 3 的所有边遍历完后,遍历 2 的所有边,此时发现 4 已经入队,则 dist[4] 就无法更新,而且 2 不会再次入队,所以 1-->4 的最短路只能经过 3,而不能经过 2。*/dist[e.to] = dist[t] + e.dis ;if (!used[e.to]){used[e.to] = 1 ;q.push (e.to) ;}}}used[t] = 0 ;}return dist[end] ;}void init (){int i ;for (i = 1 ; i <= c ; ++i)map[i].clear () ;}int main (){int i ;int x, y, h, d ;int res, low, high, mid, ans ;int tcase ;tcase = 0 ;while (scanf ("%d%d", &c, &r), c | r){EDGEe ;init () ;for (i = 1 ; i <= r ; ++i){scanf ("%d%d%d%d", &x, &y, &h, &d) ;h = (h == -1 ? INF : h) ;e.to  = y ;e.hei = h ;e.dis = d ;map[x].push_back(e) ;e.to  = x ;map[y].push_back(e) ;}scanf ("%d%d%d", &x, &y, &high) ;// 二分查找,暴力枚举所有高度low = 1 ;res = INF ;while (low <= high){mid = (low + high) / 2 ;res = spfa (x, y, mid) ;if (INF == res)high = mid - 1 ;else{low = mid + 1 ;ans = res ;h   = mid ;}}if (tcase)putchar ('\n') ;printf ("Case %d:\n", ++tcase) ;if (ans != INF){printf ("maximum height = %d\nlength of shortest route = %d\n",h, ans) ;}elseprintf ("cannot reach destination\n") ;}return 0 ;}


 

Dijkstra 解法

/* THE PROGRAM IS MADE BY PYY *//*----------------------------------------------------------------------------//Copyright (c) 2011 panyanyany All rights reserved.URL   : http://acm.hdu.edu.cn/showproblem.php?pid=2962Name  : 2962 TruckingDate  : Thursday, January 19, 2012Time Stage : 7 hoursResult: 52759342012-01-19 17:01:40Accepted29621843MS8076K2663 BC++pyyTest Data :Review :好吧,有点太浪费时间了……//----------------------------------------------------------------------------*/#include <stdio.h>#include <string.h>#define INF0x3f3f3f3f#define MAXN1002#define min(x, y)((x) < (y) ? (x) : (y))#define max(x, y)((x) > (y) ? (x) : (y))#define MEM(a, v)memset (a, v, sizeof (a))boolused[MAXN] ;intc, r ;intmap[MAXN][MAXN], heig[MAXN][MAXN], dist[MAXN], hi[MAXN] ;int dijkstra (const int beg, const int end, const int lim){int i, j ;int iMinPath, MinPath ;MEM (used, 0) ;MEM (hi, 0) ;MEM (dist, INF) ;for (i = 1 ; i <= c ; ++i){// 根据华神指点,加了这里。// 这里不加,屡次WA// 虽然后面的更新操作也限制了高度,但万一起点到终点本来就有边,// 高度却不合适呢?if (heig[beg][i] >= lim){dist[i] = map[beg][i] ;hi[i] = heig[beg][i] ;}}// 第一次 WA 后增加下两句dist[beg] = 0 ;hi[beg] = INF ;for (i = 1 ; i <= c ; ++i){iMinPath = 0 ;MinPath = INF ;for (j = 1 ; j <= c ; ++j){if (!used[j] && hi[j] >= lim &&dist[j] < MinPath){iMinPath = j ;MinPath = dist[j] ;}}used[iMinPath] = 1 ;for (j = 1 ; j <= c ; ++j){if (!used[j] && heig[iMinPath][j] >= lim &&dist[iMinPath] + map[iMinPath][j] < dist[j]){dist[j] = dist[iMinPath] + map[iMinPath][j] ;hi[j] = min(hi[iMinPath], heig[iMinPath][j]) ;}}}return dist[end] ;}int main (){int i, j ;int x, y, h, d ;int res, low, high, mid, tmp1, tmp2 ;int tcase ;tcase = 0 ;while (scanf ("%d%d", &c, &r), c | r){MEM(map, INF) ;MEM(heig, 0) ;for (i = 1 ; i <= r ; ++i){scanf ("%d%d%d%d", &x, &y, &h, &d) ;map[x][y] = map[y][x] = d ;heig[x][y] = heig[y][x] = (h == -1 ? INF : h) ;}scanf ("%d%d%d", &x, &y, &h) ;low = 1 ;// 第四次 WA,改为 1high = h ;res = INF ;while (low <= high){mid = (low + high) / 2 ;tmp1 = dijkstra (x, y, mid) ;if (INF == tmp1)high = mid - 1 ;else{low = mid + 1 ;res = tmp1 ;tmp2 = mid ;}}if (tcase)putchar ('\n') ;printf ("Case %d:\n", ++tcase) ;if (res != INF){printf ("maximum height = %d\nlength of shortest route = %d\n",tmp2, res) ;}elseprintf ("cannot reach destination\n") ;}return 0 ;}


 

原创粉丝点击