zoukankan      html  css  js  c++  java
  • Borg Maze

    poj3026:http://poj.org/problem?id=3026

    题意:在一个y行 x列的迷宫中,有可行走的通路空格’ ‘,不可行走的墙’#’,还有两种英文字母A和S,现在从S出发,要求用最短的路径L连接所有字母,输出这条路径L的总长度。
    题解:一格的长度为1,而且移动的方法只有上、下、左、右,所以在无任何墙的情况下(根据题意的“分离”规则,重复走过的路不再计算因此当使用prim算法求L的长度时,根据算法的特征恰好不用考虑这个问题(源点合并很好地解决了这个问题),L就是最少生成树的总权值W由于使用prim算法求在最小生成树,因此无论哪个点做起点都是一样的,(通常选取第一个点),因此起点不是S也没有关系所以所有的A和S都可以一视同仁,看成一模一样的顶点就可以了剩下的问题关键就是处理 任意两字母间的最短距离,由于存在了“墙#” ,这个距离不可能单纯地利用坐标加减去计算,必须额外考虑,推荐用BFS(广搜、宽搜),这是本题的唯一难点,因为prim根本直接套用就可以了。

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<algorithm>s
      5 #include<queue>
      6 #include<string>
      7 #define INF 10000000
      8 using namespace std;
      9 int xn,yn,top,pos;
     10 int n,m;
     11 char map[56][56];
     12 int dist[56][56],lowcost[2505],g[2504][2506],visit[56][56];
     13 struct Node{
     14     int x;
     15     int y;
     16     int step;
     17 };
     18 struct Node1{
     19     int x;
     20     int y;
     21 }node[2503];
     22 void init(){
     23     for(int i=1;i<=xn;i++)
     24       for(int j=1;j<=yn;j++)
     25         dist[i][j]=INF;
     26   memset(visit,0,sizeof(visit));        
     27 }
     28 void bfs(Node1 a){
     29     init();
     30     dist[a.x][a.y]=0;
     31     queue<Node>Q;
     32     Node temp;
     33     temp.x=a.x;
     34     temp.y=a.y;
     35     temp.step=0;
     36     visit[a.x][a.y]=true;
     37     Q.push(temp);
     38     while(!Q.empty()){
     39         Node tmp=Q.front();
     40         Q.pop();
     41         int x=tmp.x;
     42         int y=tmp.y;
     43     if(x>=2&&map[x-1][y]!='#'&&!visit[x-1][y]){
     44             visit[x-1][y]=true;//bfs收索时候,一定要在入队之前标记,如果在出队 
     45                dist[x-1][y]=tmp.step+1;//时在标记,会使得一个元素在队列中可能会被加入多次。
     46               temp.x=x-1;
     47               temp.y=y;
     48               temp.step=tmp.step+1;
     49               Q.push(temp);
     50                 }
     51         if(x<xn&&map[x+1][y]!='#'&&!visit[x+1][y]){
     52                visit[x+1][y]=true;
     53                dist[x+1][y]=tmp.step+1;
     54               temp.x=x+1;
     55               temp.y=y;
     56               temp.step=tmp.step+1;
     57               Q.push(temp);
     58             }
     59         if(y>=2&&map[x][y-1]!='#'&&!visit[x][y-1]){
     60                visit[x][y-1]=true;
     61                 dist[x][y-1]=tmp.step+1;
     62               temp.x=x;
     63               temp.y=y-1;
     64               temp.step=tmp.step+1;
     65               Q.push(temp);
     66            }
     67         if(y<yn&&map[x][y+1]!='#'&&!visit[x][y+1]){
     68               visit[x][y+1]=true;
     69                dist[x][y+1]=tmp.step+1;
     70               temp.x=x;
     71               temp.y=y+1;
     72               temp.step=tmp.step+1;
     73               Q.push(temp);
     74            }
     75     }
     76 }
     77 void prim(int v0){
     78     int sum=0;
     79     for(int i=1;i<top;i++){
     80         lowcost[i]=g[v0][i];
     81     }
     82     lowcost[v0]=-1;
     83     for(int i=1;i<top-1;i++){
     84         int min=INF;
     85         int v=-1;
     86         for(int j=1;j<top;j++){
     87             if(lowcost[j]<min&&lowcost[j]!=-1){
     88                 min=lowcost[j];
     89                 v=j;
     90             }
     91         }
     92         if(v!=-1){
     93             sum+=lowcost[v];
     94             lowcost[v]=-1;
     95             for(int k=1;k<top;k++)
     96              if(lowcost[k]!=-1&&g[v][k]<lowcost[k])
     97                  lowcost[k]=g[v][k];
     98         }
     99     }
    100     printf("%d
    ",sum);
    101 }
    102 int main(){
    103     int cas;string line;
    104     scanf("%d",&cas);
    105     char sss[30];
    106     while(cas--){
    107         top=1;
    108         scanf("%d%d",&yn,&xn);
    109         gets(sss);//这里如果用gethchar()oj会判wa 
    110         for(int i=1;i<=xn;i++){
    111             getline(cin,line);//读取一整行 
    112             
    113            for(int j=1;j<=yn;j++){  
    114               map[i][j]=line[j-1];
    115              if(map[i][j]!=' '&&map[i][j]!='#'){//记录每个A和S 
    116                    node[top].x=i;
    117                    node[top++].y=j;
    118                    }
    119              if(map[i][j]=='S'){//记录起点 
    120                      pos=top-1;
    121                }
    122              }
    123          }
    124          for(int i=1;i<top;i++){ 
    125               bfs(node[i]);//一遍bfs找出了所有其他点与改点的距离 
    126              for(int j=i+1;j<top;j++){//建边 
    127                g[i][j]=g[j][i]=dist[node[j].x][node[j].y];
    128              }
    129          }
    130         for(int i=1;i<top;i++)//初始化 
    131           for(int j=1;j<top;j++){
    132               if(i==j)g[i][j]=0;
    133               else if(g[i][j]==0)g[i][j]=INF;
    134           }
    135           prim(pos);     
    136      }
    137 }
    View Code

  • 相关阅读:
    [转]Flex PieChart
    Flash Builder 4 下载
    [转]Android如何防止apk程序被反编译
    [转]自定义Spinner五步走
    [转]coolpad 获得 root
    [转]c# .net 用程序画图 曲线图
    android ContentProvider 遭遇 failed to find provider info
    [转]如何把多个Android Project打包成一个APK
    android loading界面 及 处理
    [转]android中生成和使用jar 分享
  • 原文地址:https://www.cnblogs.com/chujian123/p/3377822.html
Copyright © 2011-2022 走看看