zoukankan      html  css  js  c++  java
  • Borg Maze POJ

     

    题目链接:https://vjudge.net/problem/POJ-3026

    题意:题目讲的其实有点迷糊。。。总的来说就是,在一个地图上,你需要把所有的‘A’和‘S’连接起来,使得所有线段累加长度最短,那么很显然,这里需要最小生成树。

    思路:地图上分布着‘A’和‘S’,我们需要把图上的信息提取出一个图,G(V,E)。那么我们就可以用prime算法了。

    开始,我们可以先把‘A’和‘S’编号,然后用bfs跑地图,枚举每个‘A’和‘S’其他的‘A’和‘S’的距离,先生成一个距离矩阵,生成了矩阵之后,就可以套prime板子了。

    建图是关键,代码中会有些解释


      1 #include <iostream>
      2 #include <cstring>
      3 #include<vector>
      4 #include<string>
      5 #include <cmath>
      6 #include <map>
      7 #include <queue>
      8 #include <algorithm>
      9 #include <cstdio>
     10 using namespace std;
     11 
     12 #define inf 99999
     13 #define rep(i,j,k) for(int i = (j); i <= (k); i++)
     14 #define rep__(i,j,k) for(int i = (j); i < (k); i++)
     15 #define per(i,j,k) for(int i = (j); i >= (k); i--)
     16 #define per__(i,j,k) for(int i = (j); i > (k); i--)
     17 
     18 
     19 const int N = 110;
     20 int mv_x[] = {0,0,1,-1};
     21 int mv_y[] = {1,-1,0,0};
     22 int G[N][N]; //路线
     23 string mp[N]; //原始地图
     24 int num[N][N];//编号图
     25 bool vis[N][N];//bfs
     26 int sx,sy;//S
     27 int n,m;
     28 int cnt;//编号
     29 
     30 struct node{
     31 
     32     int x,y,v;
     33 };
     34 
     35 
     36 void init_G(){
     37 
     38     rep(i,1,cnt){
     39         rep(j,1,cnt){
     40             if(i == j) G[i][j] = 0;
     41             else G[i][j] = inf;
     42         }
     43     }
     44 }
     45 
     46 void set_num(){
     47     
     48     cnt = 0;
     49     rep__(i,0,n){
     50         rep__(j,0,m){
     51             if(mp[i][j] == 'A' || mp[i][j] == 'S') num[i][j] = ++cnt; //把‘A’和‘S’编号
     52         }
     53     }
     54 }
     55 
     56 inline bool check(int x,int y){
     57     return x >= 0 && x < n && y >= 0 && y < m;
     58 }
     59 
     60 void bfs(int now_x,int now_y){
     61 
     62     memset(vis,0,sizeof(vis));
     63 
     64     int po = num[now_x][now_y]; //该点的编号
     65 
     66     queue<node > que;
     67     que.push(node{now_x,now_y,0});
     68     vis[now_x][now_y] = true;
     69 
     70     while(!que.empty()){
     71 
     72         node tmp = que.front();
     73         que.pop();
     74 
     75         //遇到了其他的点,得到一条边
     76         if(mp[tmp.x][tmp.y] == 'A' || mp[tmp.x][tmp.y] == 'S'){ 
     77             G[po][num[tmp.x][tmp.y]] = min(G[po][num[tmp.x][tmp.y]],tmp.v);
     78         }
     79 
     80         rep__(p,0,4){
     81             
     82             int dx = tmp.x + mv_x[p];
     83             int dy = tmp.y + mv_y[p];
     84 
     85             if(check(dx,dy) && mp[dx][dy] != '#' && !vis[dx][dy]){
     86 
     87                 vis[dx][dy] = true;
     88 
     89                 que.push(node{dx,dy,tmp.v + 1});
     90             }
     91         }
     92     }
     93 
     94 }
     95 
     96 void work(){
     97 
     98     rep__(i,0,n){
     99         rep__(j,0,m){
    100             if(mp[i][j] == 'A' || mp[i][j] == 'S'){
    101                 bfs(i,j); //每个点跑bfs
    102             }
    103         }
    104     }
    105 }
    106 
    107 //prime板子
    108 int prime(){
    109 
    110     bool VIS[N];
    111     int dis[N];
    112     memset(VIS, 0, sizeof(VIS));
    113 
    114     rep(i,1,cnt) dis[i] = G[1][i];
    115 
    116     VIS[1] = true;
    117 
    118     rep(i,2,cnt){
    119 
    120         int x = i;
    121         int vv = inf;
    122 
    123         rep(j,1,cnt){
    124             if(!VIS[j] && vv > dis[j]) vv = dis[x = j];
    125         }
    126         
    127         if(x == -1) continue;
    128 
    129         VIS[x] = 1;
    130 
    131         rep(j,1,cnt){
    132             if(!VIS[j] && dis[j] > G[x][j])
    133                 dis[j] = G[x][j];
    134         }
    135     }
    136 
    137     int sum = 0;
    138     rep(i,1,cnt) sum += dis[i];
    139 
    140     return sum;
    141 }
    142 
    143 
    144 int main(){
    145 
    146 
    147     int T;
    148     scanf("%d",&T);
    149 
    150     while(T--){
    151 
    152         scanf("%d%d
    ",&m,&n);
    153 
    154         rep__(i,0,n) gets(mp[i]);    
    155 
    156         set_num();//设置编号
    157         init_G(); //初始化G
    158         work();
    159         
    160 
    161         // rep(i,1,cnt){
    162         //     rep(j,1,cnt) printf("%d",G[i][j]);
    163         //     printf("
    ");
    164         // }
    165 
    166         // printf("ans
    ");
    167         printf("%d
    ",prime());
    168 
    169     }
    170 
    171 
    172     getchar();getchar();
    173     return 0;
    174 }
  • 相关阅读:
    移动端跨平台方案对比:React Native、weex、Flutter
    js json处理 双引号
    jquery 发get post请求
    librtmp编译for android and ios 不要openssl
    mysql reset password重置密码
    pdf ppt word office转图片 教学白板
    使用阻塞队列实现生产者-消费者模型
    ThreadPoolExecutor线程池的分析和使用
    HashMap HashTable和ConcurrentHashMap的区别
    HTTP协议GET和POST请求的区别
  • 原文地址:https://www.cnblogs.com/SSummerZzz/p/11234966.html
Copyright © 2011-2022 走看看