• poj 3026 Borg Maze(bfs+最小生成树)


    题目:http://poj.org/problem?id=3026

    题意真的很难懂。。。

    题目大意:一个迷宫,'#'是墙,不可行走,‘ ‘是可行走的,现在题目是要求从s出发把所有的字母(‘A’)连起来的最短路径

    各个字母的边权用bfs可求:墙不可走,超出矩阵范围不可走,建立任意字母之间最短距离的图

    最后用prim就可以了

    注:用getchar会wa,不知道为什么。。。

    View Code
      1 #include <iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #define inf 3000
      5 using namespace std;
      6 char map[105][105];//存储原始的迷宫
      7 int no[105][105];//记录字母的下标,map[i][j]是否为字母
      8 struct node
      9 {
     10     int x,y;
     11     int num;
     12 }que[2510];
     13 int nonde[4][2]={{0,-1},{0,1},{1,0},{-1,0}};//移动的方向
     14 int cmap[105][105];//存储各个字母之间的最短距离
     15 int n,m;
     16 int nnum;//字母的总数
     17 void bfs(int i,int j)
     18 {
     19     int vis[105][105];
     20     int head,tail;
     21     memset(vis,0,sizeof(vis));
     22     head=tail=0;
     23     que[head].x=i;
     24     que[head].y=j;
     25     que[head].num=0;
     26     vis[i][j]=1;
     27     tail++;
     28     while(head<tail)
     29     {
     30         if(no[que[head].x][que[head].y])
     31         {
     32             cmap[no[i][j]][no[que[head].x][que[head].y]]=que[head].num;//将此时的字母间的最短路径放入cmap
     33         }
     34         for(int k=0;k<4;k++)
     35         {
     36             int kx=que[head].x+nonde[k][0];
     37             int ky=que[head].y+nonde[k][1];
     38             if(kx>=1&&kx<=m&&ky>=1&&ky<=n)
     39             {
     40                 if(!vis[kx][ky]&&map[kx][ky-1]!='#')
     41                 {
     42                     que[tail].x=kx;
     43                     que[tail].y=ky;
     44                     que[tail].num=que[head].num+1;
     45                     vis[kx][ky]=1;
     46                     tail++;
     47                 }
     48             }
     49         }
     50         head++;
     51     }
     52     return ;
     53 }
     54 void prim()
     55 {
     56     int dis[105];
     57     int viss[105];
     58     int i,j;
     59     memset(viss,0,sizeof(viss));
     60     for(i=1;i<=nnum;i++)
     61     {
     62         dis[i]=cmap[1][i];
     63     }
     64     viss[1]=1;
     65     int min,pos;
     66     int ans=0;
     67     for(i=1;i<=nnum;i++)
     68     {
     69        min=inf;
     70        for(j=2;j<=nnum;j++)
     71        {
     72            if(!viss[j]&&min>dis[j])
     73            {
     74                pos=j;
     75                min=dis[j];
     76            }
     77        }
     78        if(min==inf)
     79        break;
     80        viss[pos]=1;
     81        ans+=min;
     82        for(j=2;j<=nnum;j++)
     83        {
     84            if(!viss[j]&&dis[j]>cmap[pos][j])
     85            dis[j]=cmap[pos][j];
     86        }
     87     }
     88     printf("%d\n",ans);
     89 }
     90 int main()
     91 {
     92     int t,i,j;
     93     scanf("%d",&t);
     94     while(t--)
     95     {
     96         scanf("%d%d",&n,&m);
     97         char temp[51];
     98         gets(temp);//用getchar()会wa
     99         memset(no,0,sizeof(no));
    100         nnum=0;
    101         for(i=1;i<=m;i++)
    102         {
    103             gets(map[i]);
    104             for(j=0;j<n;j++)
    105             {
    106                 if(map[i][j]=='A'||map[i][j]=='S')
    107                 {
    108                     nnum++;
    109                     no[i][j+1]=nnum;
    110                 }
    111             }
    112         }
    113         for(i=1;i<=m;i++)
    114         {
    115             for(j=1;j<=n;j++)
    116             {
    117                 if(no[i][j])
    118                 bfs(i,j);//[i][j]到其他点的边权
    119             }
    120         }
    121         prim();
    122     }
    123 
    124     return 0;
    125 }
  • 相关阅读:
    hnust Snowman
    hnust 可口可乐大促销
    hnust 聚宝盆
    hnust 搬书
    hnust 神奇的序列
    hnust 懒人多动脑
    hnust CZJ-Superman
    集合Set--BST实现
    快速排序
    位运算符
  • 原文地址:https://www.cnblogs.com/wanglin2011/p/2812274.html
Copyright © 2020-2023  润新知