IAML's Blog

Find passion in coding
sicily1684 Christmas
poj1837 Balance

sicily1702 Robot Roll Call -- Cambot...Servo...Gypsy...Croooow

IAmL posted @ 2009年4月20日 07:30 in 解题报告 with tags sicily1702解题报告 , 3074 阅读

这题是周赛题,当时我的想法是回溯,当然是超时,但是我还是试了,真是sb。之后就是想到把原来的图换成另外一个图。具体做法是首先把点从1~n^2编号,点(i,j)的编号为i*j。然后由于点(i, j)和它上下左右的点相连,所以i*j就和(i-1)*j,(i+1)*j,i*(j-1),i*(j+1)相连,他们的权值就是(i,j)的权值。之后用dijkstra求出最短路,再加上点(n-1,n-1)的权值就可以了。虽然说这个方法可行,但是很麻烦,超时的可能性很大,而且但是心情不好,所以我当时就没有试,后来在bbs上看到了和我思路差不多的算法,才验证了这个思路的可行性。

但是之后发现了一个更厉害的算法,就是BFS,但是该算法的提出者称之为:激情小广搜。呵呵。主要思路就是:用f[i][j]记录到(i,j)的最短路径,然后对(i,j)进行扩展的条件是找到从某个点到(i,j)这一点的新的最短路小于原来的f[i][j]。这个思路和我之前做过的广搜的不同之处就是加入了剪枝,而且不是不是纯粹的对状态进行搜索,而是对最优解答案进行搜索。从个人感觉上,有点像dp……

=======不明真相的分割线==========

 

#pragma warning(disable:4786)
#include <iostream>
#include <queue>
using namespace std;

#define N 130

int m[N][N], f[N][N], n;
const int move[4][2] = {{0, -1}, {0, 1}, {1, 0}, {-1, 0}};

struct point
{
        int x, y;
}p;

void BFS()
{
        queue<point> q;
        int x, y, k, tmp;

        for (x = 0; x < n; x++)
                for (y = 0; y < n; y++)
                        f[x][y] = 2500;

        p.x = 0;
        p.y = 0;
        f[0][0] = m[0][0];

        q.push(p);

        while (!q.empty())
        {
                p = q.front();
                q.pop();

                x = p.x;
                y = p.y;

                for (k = 0; k < 4; k++)
                {
                        p.x += move[k][0];
                        p.y += move[k][1];

                        if (p.x >= 0 && p.x < n && p.y >= 0 && p.y < n)
                        {
                                tmp = f[x][y] + m[p.x][p.y];
                                if (f[p.x][p.y] > tmp)
                                {
                                        f[p.x][p.y] = tmp;
                                        q.push(p);
                                }                            
                        }

                        p.x = x;
                        p.y = y;
                }
        }       
}

int main()
{
        int i, j, tn = 0;

        while (cin >> n, n)
        {
                tn++;

                for (i = 0; i < n; i++)
                        for (j = 0; j < n; j++)
                                cin >> m[i][j];

                BFS();

                cout << "Problem " << tn << ": " << f[n - 1][n - 1] << endl;       
        }

        return 0;
}
 

 

 


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter