Chinaunix首页 | 论坛 | 博客
  • 博客访问: 71283
  • 博文数量: 41
  • 博客积分: 1475
  • 博客等级: 上尉
  • 技术积分: 440
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-27 22:49
文章分类
文章存档

2012年(8)

2011年(1)

2009年(32)

我的朋友
最近访客

分类: C/C++

2012-03-31 17:51:28

题目: 

思路: (BFS and MST)

注意到题目中有这样一句话:
Whenever an alien is assimilated, or at the beginning of the search, the group may split in two or more groups (but their consciousness is still collective.)。 

最开始只看到"split into two", 结果走了不少弯路。让人想起高中老师一句话,“做题看到半截就开始做,你还做得安逸得很“。这在工作中也一样,做事一定要仔细,仔细可以弥补你的不足,仔细可以少犯很多不必要的错误。

言归正转,看到上面那句题意,我们就可以转换成,求最小生成树的问题。我们不用区分borg和
alien,把它们都看作是图中的节点即可,先求每个节点之间的最短路径,然后使用Kruskal或者Prim算法生成MST即可。

代码:

点击(此处)折叠或打开

  1. //
  2. // UVA 10307
  3. //
  4. // Author: xfye
  5. // Status: AC
  6. //
  7. // First, find the shortest path between each node.
  8. // Then, generate MST for these nodes and the weight
  9. // of the MST is our result.
  10. //

  11. #include <iostream>
  12. #include <cstring>
  13. #include <vector>
  14. #include <queue>

  15. using namespace std;

  16. #define MAX_MAZE_WIDTH 51
  17. #define MAX_ALIENS 100
  18. // MAX_ALIENS and a start borg
  19. #define MAX_NODES MAX_ALIENS + 1

  20. #define INF 0x7fffffff

  21. struct Position
  22. {
  23.     Position(int r, int c)
  24.         : row(r),
  25.           col(c)
  26.     {
  27.     }
  28.     Position()
  29.     {
  30.         row = 0;
  31.         col = 0;
  32.     }
  33.     int row;
  34.     int col;
  35. };

  36. //
  37. // maze information
  38. //
  39. char g_maze[MAX_MAZE_WIDTH][MAX_MAZE_WIDTH];
  40. int g_mazeRows;
  41. int g_mazeCols;
  42. Position g_nodes[MAX_NODES];
  43. int g_numNodes;

  44. //
  45. // g_nodes[i][j] is the length from node i to node j.
  46. //
  47. int g_weights[MAX_NODES][MAX_NODES];

  48. //
  49. // Use prim algorithm to generate MST for these nodes.
  50. //
  51. void generateMST()
  52. {
  53.     int visitedHT[MAX_NODES];
  54.     int numLeftNodes = g_numNodes;

  55.     memset(visitedHT, 0, sizeof(visitedHT));

  56.     vector<int> connectedNodes;
  57.     connectedNodes.push_back(0); // Select one node at first
  58.     int numConnectedNodes = 1;
  59.     int result = 0;
  60.     visitedHT[0] = 1;

  61.     while (numConnectedNodes < g_numNodes) {
  62.         int nextNode = 0;
  63.         int nextEdgeWeight = INF;
  64.         for (int i = 0; i < connectedNodes.size(); i++) {
  65.             int tmpWeight = INF;
  66.             int tmpNode = 0;
  67.             for (int k = 0; k < g_numNodes; k++) {
  68.                 if (g_weights[connectedNodes[i]][k] != 0 && !visitedHT[k]) {
  69.                     if (tmpWeight > g_weights[connectedNodes[i]][k]) {
  70.                         tmpWeight = g_weights[connectedNodes[i]][k];
  71.                         tmpNode = k;
  72.                     }
  73.                 }
  74.             }
  75.             if (nextEdgeWeight > tmpWeight) {
  76.                 nextEdgeWeight = tmpWeight;
  77.                 nextNode = tmpNode;
  78.             }
  79.         }

  80.         connectedNodes.push_back(nextNode);
  81.         visitedHT[nextNode] = 1;
  82.         result += nextEdgeWeight;
  83.         numConnectedNodes++;
  84.     }

  85.     cout << result << endl;
  86. }

  87. void doBFS(int nodeIndex)
  88. {
  89.     int visited[MAX_MAZE_WIDTH][MAX_MAZE_WIDTH];
  90.     memset(visited, 0, sizeof(visited));

  91.     int step = 0;
  92.     queue<Position> queue1;
  93.     queue<Position> queue2;
  94.     queue1.push(g_nodes[nodeIndex]);
  95.     visited[g_nodes[nodeIndex].row][g_nodes[nodeIndex].col] = 1;

  96.     int numVisitedNodes = 1;
  97.     queue<Position> *nextQueue = &queue1;
  98.     while (!nextQueue->empty()) {
  99.         queue<Position> *curQueue = nextQueue;
  100.         if (nextQueue == &queue1) {
  101.             nextQueue = &queue2;
  102.         } else {
  103.             nextQueue = &queue1;
  104.         }
  105.         step++;
  106.         while (curQueue->size()) {
  107.             Position pos = curQueue->front();
  108.             curQueue->pop();

  109.             //
  110.             // Try to go the four directions
  111.             //
  112.             for (int i = 0; i < 4; i++) {
  113.                 Position nextPos = pos;
  114.                 nextPos.row += (% 2) ? 0 : i - 1;
  115.                 nextPos.col += (% 2) ? i - 2 : 0;
  116.                 if (nextPos.row >= 0
  117.                     && nextPos.row + 1 < g_mazeRows
  118.                     && nextPos.col >= 0
  119.                     && nextPos.col + 1 < g_mazeCols
  120.                     && g_maze[nextPos.row][nextPos.col] != '#'
  121.                     && !visited[nextPos.row][nextPos.col]) {
  122.                     nextQueue->push(nextPos);
  123.                     if (g_maze[nextPos.row][nextPos.col] != ' ') {
  124.                         // Meets a node
  125.                         if (g_weights[nodeIndex][g_maze[nextPos.row][nextPos.col]] ==0
  126.                             || g_weights[nodeIndex][g_maze[nextPos.row][nextPos.col]]> step) {
  127.                             g_weights[nodeIndex][g_maze[nextPos.row][nextPos.col]] = step;
  128.                         }
  129.                     }
  130.                     visited[nextPos.row][nextPos.col] = 1;
  131.                 }
  132.             }
  133.         }
  134.     }
  135. }

  136. int main()
  137. {
  138.     int numCases;

  139.     cin >> numCases;
  140.     for (int i = 0; i < numCases; i++) {
  141.         //
  142.         // Reads maze information
  143.         //
  144.         cin >> g_mazeCols >> g_mazeRows;
  145.         g_numNodes = 0;
  146.         cin.ignore(1);
  147.         for (int j = 0; j < g_mazeRows; j++) {
  148.             cin.getline(g_maze[j], MAX_MAZE_WIDTH);
  149.             for (int k = 0; k < g_mazeCols; k++) {
  150.                 switch (g_maze[j][k]) {
  151.                 case 'S':
  152.                 case 'A':
  153.                     // Here, let g_maze[j][k] store the ID of the node.
  154.                     g_maze[j][k] = g_numNodes;
  155.                     g_nodes[g_numNodes].row = j;
  156.                     g_nodes[g_numNodes].col = k;
  157.                     g_numNodes++;
  158.                     break;
  159.                 default:
  160.                     break;
  161.                 }
  162.             }
  163.         }

  164.         memset(g_weights, 0, sizeof(g_weights));

  165.         //
  166.         // Use BFS on each node to find all the shortest path between
  167.         // each node.
  168.         //
  169.         for (int k = 0; k < g_numNodes; k++) {
  170.             doBFS(k);
  171.         }

  172.         generateMST();
  173.     }
  174. }
阅读(895) | 评论(0) | 转发(0) |
0

上一篇:ACM UVA 10306 (e-Coins)

下一篇:没有了

给主人留下些什么吧!~~