POJ3026 最小生成树

问题: POJ3026

分析:

采用BFS算出两两之间的距离,再用PRIM算法计算最小生成树。

AC代码:

  1 //Memory: 220K        Time: 32MS
  2 #include <iostream>
  3 #include <cstdio>
  4 #include <string>
  5 #include <cstring>
  6 #include <queue>
  7
  8 using namespace std;
  9
 10 const int maxn = 52;
 11 const int max_alien = 101;
 12 char maze[maxn][maxn];
 13 int m[maxn][maxn];
 14 int g[max_alien][max_alien];
 15 int vis[maxn][maxn];
 16 int v[max_alien + 1];
 17 int d[max_alien + 1];
 18 int alien;
 19 int test, x, y;
 20 int si[max_alien + 1], sj[max_alien + 1];
 21 int step[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
 22
 23 struct node
 24 {
 25     int i;
 26     int j;
 27     int d;
 28     void set(int ii, int jj)
 29     {
 30         i = ii;
 31         j = jj;
 32         d = 0;
 33     }
 34 }n1, n2;
 35
 36 queue<struct node> q;
 37
 38 void bfs(int num, int i, int j)
 39 {
 40     memset(vis, 0, sizeof(vis));
 41     int t = alien - num;
 42     while ( !q.empty() ) q.pop();
 43     n1.set(i, j);
 44     q.push(n1);
 45
 46     while ( !q.empty() && t > 0 ){
 47         n1 = q.front();
 48         q.pop();
 49
 50         for (int i = 0; i < 4; i++){
 51             n2.set(n1.i + step[i][0], n1.j + step[i][1]);
 52             /*if (n2.i < 0 || n2.j < 0 ||)*/
 53             if (maze[n2.i][n2.j] == ‘#‘ || vis[n2.i][n2.j]) continue;
 54
 55             vis[n2.i][n2.j] = 1;
 56             n2.d = n1.d + 1;
 57
 58             if (m[n2.i][n2.j] > num){
 59                 t--;
 60                 g[num][ m[n2.i][n2.j] ] = g[ m[n2.i][n2.j] ][num] = n2.d;
 61             }
 62
 63             q.push(n2);
 64         }
 65     }
 66
 67 }
 68
 69 int prim()
 70 {
 71     memset(v, 0, sizeof(v));
 72     v[0] = 1;
 73     int ret = 0;
 74     for (int i = 1; i <= alien; i++)
 75         d[i] = g[0][i];
 76
 77     for (int i = 0; i < alien; i++) {
 78
 79         int _min = 3000, ix;
 80         for (int j = 1; j <= alien; j++) {
 81             if ( !v[j] && d[j] < _min){
 82                 _min = d[j];
 83                 ix = j;
 84             }
 85         }
 86         v[ix] = 1;
 87         ret += d[ix];
 88
 89         for (int j = 1; j <= alien; j++){
 90             if (!v[j] && d[j] > g[ix][j])
 91                 d[j] = g[ix][j];
 92         }
 93     }
 94     return ret;
 95 }
 96
 97 int main()
 98 {
 99     scanf("%d", &test);
100     while (test--){
101         memset(m, 0, sizeof(m));
102         scanf("%d%d", &x, &y);
103         gets(maze[0]);
104         alien = 0;
105         for (int i = 0; i < y; i++)
106             gets(maze[i]);
107         for (int i = 0; i < y; i++){
108             for (int j = 0; j < x; j++){
109                 if (maze[i][j] == ‘S‘){
110                     si[0] = i;
111                     sj[0] = j;
112                 }
113                 else if (maze[i][j] == ‘A‘) {
114                     m[i][j] = ++alien;
115                     si[alien] = i;
116                     sj[alien] = j;
117                 }
118             }
119         }
120
121         memset(g, 0, sizeof(g));
122         for (int i = 0; i <= alien; i++){
123             bfs(i, si[i], sj[i]);
124         }
125
126         int ans = prim();
127
128         printf("%d\n", ans);
129     }
130     return 0;
131 }

POJ3026 最小生成树

时间: 2024-08-27 12:11:37

POJ3026 最小生成树的相关文章

POJ3026——Borg Maze(BFS+最小生成树)

Borg Maze DescriptionThe Borg is an immensely powerful race of enhanced humanoids from the delta quadrant of the galaxy. The Borg collective is the term used to describe the group consciousness of the Borg civilization. Each Borg individual is linked

POJ-3026 Borg Maze---BFS预处理+最小生成树

题目链接: https://vjudge.net/problem/POJ-3026 题目大意: 在一个y行 x列的迷宫中,有可行走的通路空格' ',不可行走的墙'#',还有两种英文字母A和S,现在从S出发,要求用最短的路径L连接所有字母,输出这条路径L的总长度. 思路: 先BFS预处理出所有的字母之间的距离,然后用prim模板 超级坑的是这里得用gets()吃掉回车符,用getchar()会WA 1 #include<iostream> 2 #include<cstdio> 3 #

最小生成树练习3(普里姆算法Prim)

风萧萧兮易水寒,壮士要去敲代码.本女子开学后再敲了.. poj1258 Agri-Net(最小生成树)水题. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int inf=0x3f3f3f3f; 6 const int N=101; 7 int n,m; 8 int g[N][N],low[N]; 9 void prim(int u0

poj3026(Borg Maze)

题目大意: 在银河系中有一强大生物个体Borg,每个个体之间都有一种联系.让我们帮忙写个程序扫描整个迷宫并同化隐藏在迷宫的相异个体的最小代价.A 代表相异个体.空格代表什么没有,#代表障碍,S为开始点.扫描可以上下左右.测试数据: 2 6 5 ##### #A#A## # # A# #S ## ##### 7 7 ##### #AAA### # A# # S ### # # #AAA### ##### 解题思路: 简化题意就是从最少需要多少步将S和所有的A联系起来.第一组事例:S->A(1,1)

「题解」kuangbin 最小生成树

POJ-1251 Jungle Roads (水题,%c) POJ-1287 Networking (水) POJ-2031 Building a Space Station (%f浮点数尴尬精度,两球间距离) POJ-2421 Constructing Roads (一些边已建好,简单处理一下) ZOJ-1586 QS Network (处理一下边权) HDU-1233 还是畅通工程 (水) HDU-1875 畅通工程再续 (浮点数,条件连边) HDU-1301 Jungle Roads (重

次最小生成树 模版

次小生成树(转) 转载(http://www.cnblogs.com/z360/p/6875488.html) 所谓次小生成树,顾名思义就是从生成树中取出的第二小的生成树. 我们在前面已经说过最小生成树的概念及代码实现了,所以接下来要说的次小生成树应该比较简单理解了. 求次小生成树的两种方法 1:首先求出最小生成树T,然后枚举最小生成树上的边,计算除了枚举的当前最小生成树的边以外的所有边形成的最小生成树Ti,然后求最小的Ti就是次小生成树.2:首先计算出最小生成树T,然后对最小生成树上任意不相邻

HDU1863 畅通工程---(最小生成树)

畅通工程 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 27972    Accepted Submission(s): 12279 Problem Description 省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可).经过调查评估,得到的统计表中列出

51Nod1601 完全图的最小生成树计数

传送门 我居然忘写题解啦!(记忆废) 不管怎么说,这题还算是一道好题啊--你觉得敦爷出的题会有水题么 -- 这题比较容易把人误导到Boruvka算法之类的东西上去(我们机房去刚D题的人一开始大多也被误导了),但仔细思考之后是可以发现问题的特殊性质的. 听说很多人是从Kruskal算法想到这道题的做法的?好吧我并不是,那我就写写我的思考过程好了-- 记得算导上有一道思考题,判断一个最小生成树算法的正确性.那个算法是这样的:把当前图的点集随意划分成两半,递归两半后选出连接两个点集的边中权值最小的一条

最小生成树求法 Prim + Kruskal

prim算法的思路 和dijkstra是一样的 每次选取一个最近的点 然后去向新的节点扩张 注意这里的扩张 不再是 以前求最短路时候的到新的节点的最短距离 而是因为要生成一棵树 所以是要连一根最短的连枝 所以关键部分修改一下 dist[u] = min(dist[u], e.cost) --->>e是连接 v 和 u的边 同样地 普同写法O(v^2) 用队列优化后O(E*logV) 1 #include <iostream> 2 #include <stdio.h> 3