Coder Space

PKU 3026 Borg Maze--- 最小生成树,Prim算法

题意较为费解,仔细阅读理解题意,本题就是一个最小生成树问题,其中图的顶点是所有的alein和那个Borg,每两个顶点之间都有边连通,边的权重就是两个顶点间最小距离,这个最小距离可以用广度优先搜索算法(BFS)求出,最后用Prim算法求出最小生成树的长度即为答案。

注意:

(1)首先,注意输入x,y要用gets()来去末尾的空格。
(2)输入maze时,要用gets(),否则会接收不到空格。
(3)用BFS来将maze中噶字母变成转化成无向图,用邻接矩阵表示。
(4)用prim求最小生成树。

  1#include<iostream>
  2#include<string>
  3#include<limits>
  4#include<queue>
  5
  6using namespace std;
  7
  8const int maxXY = 51;
  9const int maxA = 102;           //S当作A处理,故最大alien数为101
 10
 11const int INF = numeric_limits<int>::max();
 12
 13char maze[maxXY][maxXY];
 14int mazeInt[maxXY][maxXY];
 15int G[maxA][maxA];
 16
 17struct Point
 18{
 19    int r;     //row
 20    int c;     //column
 21    int w;
 22}
;
 23
 24//BFS算法求Alien之间的距离
 25void BFS(Point point,int x,int y)
 26{
 27    int dir[4][2= {1,0,-1,0,0,1,0,-1};
 28
 29    queue<Point> q;
 30    Point cur,nex;
 31
 32    bool flag[maxXY][maxXY];
 33
 34    for(int i=0; i<y; i++)
 35    {
 36        for(int j=0; j<x; j++)
 37        {
 38            flag[i][j] = false;
 39        }

 40    }

 41
 42    point.w = 0;
 43    flag[point.r][point.c] = true;
 44    q.push(point);
 45
 46    while(!q.empty())
 47    {
 48        cur = q.front();
 49        q.pop();
 50
 51        for(int i=0; i<4; i++)
 52        {
 53            nex.r = cur.r + dir[i][0];
 54            nex.c = cur.c + dir[i][1];
 55
 56            int temp = mazeInt[nex.r][nex.c];
 57
 58            if((!flag[nex.r][nex.c]) && temp >= 0)
 59            {
 60                
 61                nex.w = cur.w + 1;                
 62                flag[nex.r][nex.c] = true;
 63                q.push(nex);
 64
 65                if(temp > 0)
 66                {
 67                    G[mazeInt[point.r][point.c]][temp] = nex.w;
 68                }

 69            }

 70        }

 71    }

 72}

 73
 74//Prim算法求最小生成树
 75int Prim(int n)
 76{
 77    int lowcost[maxA];             //到当前部分生成树的最小距离值
 78    bool flag[maxA];
 79
 80    flag[1= true;
 81    for(int i=2; i<=n; i++)
 82    {
 83        lowcost[i] = G[1][i];
 84        flag[i] = false;
 85    }

 86
 87    for(int i=1; i<n; i++)
 88    {
 89        int temp = INF;
 90        int v = 1;
 91
 92        //搜索下一条最短边加入生成树
 93        for(int j=2; j<=n; j++)
 94        {
 95            if((!flag[j]) && (lowcost[j] < temp))
 96            {
 97                temp = lowcost[j];
 98                v = j;
 99            }

100        }

101        flag[v] = true;
102
103        //更新操作
104        for(int j=2; j<=n; j++)
105        {
106            if((!flag[j]) && (G[v][j] < lowcost[j]))
107            {
108                lowcost[j] = G[v][j];
109            }

110        }

111    }

112    
113    int sumLen = 0;
114    for(int i=2; i<=n; i++)
115    {
116        sumLen += lowcost[i];
117    }

118    
119    return sumLen;
120}

121
122
123int main()
124{
125    int N;
126    int x,y;
127    int nAlien;
128
129    char c[100];
130
131    Point point;
132
133    int i,j;
134
135    cin>>N;
136    while(N--)
137    {
138        cin>>x>>y;
139        gets_s(c);
140
141        for(i=0; i<y; i++)
142        {
143            gets_s(maze[i]);
144        }

145
146        //把符号迷宫转化为整数迷宫,对alien编号
147        nAlien = 0;
148        for(i=0; i<y; i++)
149        {
150            for(j=0; j<x; j++)
151            {
152                switch(maze[i][j])
153                {
154                case '#':
155                    mazeInt[i][j] = -1;
156                    break;
157
158                case ' ':
159                    mazeInt[i][j] = 0;
160                    break;
161
162                case 'A':                       //把S直接当A处理,但要注意maxA即就101了
163                case 'S':
164                    mazeInt[i][j] = ++nAlien;
165                    break;
166                }

167            }

168        }

169
170        //构造邻接矩阵
171        for(i=0; i<y; i++)
172        {
173            for(j=0; j<x; j++)
174            {
175                if(mazeInt[i][j] > 0)
176                {
177                    point.r = i;
178                    point.c = j;
179                    BFS(point,x,y);
180                }

181            }

182        }

183
184        //求最小生成树
185        cout<<Prim(nAlien)<<endl;
186    }

187    return 0;
188}
        
189

posted on 2010-05-14 02:09 David Liu 阅读(428) 评论(0)  编辑 收藏 引用 所属分类: 图论


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


My Links

Blog Stats

常用链接

留言簿

文章分类

文章档案

搜索

最新评论