|
发表于 2022-1-14 21:28:33
|
显示全部楼层
典型的光度搜索。
- /*
- 答案:260324
- 耗时:0.023621秒(单核)
- 0.005743秒(六核)
- */
- #include <cstdio>
- #include <algorithm>
- #include <queue>
- #include <omp.h>
- using namespace std;
- //四个方向
- const int nDR[] = { 1,0,-1,0 };
- const int nDC[] = { 0,1,0,-1 };
- char cVisited[80][80];
- int m[80][80];
- struct stNode
- {
- int r, c;
- int nSum;
- bool operator<(const stNode &n) const
- {
- return (nSum > n.nSum);
- }
- };
- int main(void)
- {
- double t = omp_get_wtime();
- FILE *fin = NULL;
- freopen_s(&fin, "p082_matrix.txt", "r", stdin);//打开文件
- //读入数据
- for (int i = 0; i < 80; ++i)
- {
- for (int j = 0; j < 79; ++j)
- scanf_s("%d,", &(m[i][j]));
- scanf_s("%d", &(m[i][79]));
- }
- fclose(fin);
- int nMinSum = 0x7fffffff;
- #pragma omp parallel for shared(m) reduction(min:nMinSum)
- for (int r = 0; r < 80; ++r)//对第一列进行循环
- {
- char cVisited[80][80];//访问过的标志
- priority_queue<stNode> q;//优先队列
- //初始化数据
- memset(cVisited, 0, sizeof(cVisited));
- stNode nTemp;
- nTemp.r = r;
- nTemp.c = 0;
- nTemp.nSum = m[r][0];
- cVisited[r][0] = 1;
- q.push(nTemp);
- while (!q.empty())//广搜
- {
- stNode nTop = q.top();//取出和最小的点
- q.pop();
- if (nTop.c == 79)//如果以到终点
- {
- nMinSum = min(nMinSum, nTop.nSum);
- break;
- }
- for (int i = 0; i < 4; ++i)//从当前点向周围四个方向探索
- {
- int nr = nTop.r + nDR[i];
- int nc = nTop.c + nDC[i];
- if (nr >= 0 && nr < 80 && nc >= 0 && nc < 80 && cVisited[nr][nc] == 0)//检查新探索的点是否合法或尚未访问过
- {
- cVisited[nr][nc] = 1;
- nTemp.r = nr;
- nTemp.c = nc;
- nTemp.nSum = nTop.nSum + m[nr][nc];
- q.push(nTemp);
- }
- }
- }
- }
- t = omp_get_wtime() - t;
- printf_s("%d\n%lf\n", nMinSum, t);
- return 0;
- }
复制代码 |
|