zoukankan      html  css  js  c++  java
  • POJ 3026(BFS+prim)

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

    题意:任意两个字母可以连线,求把所有字母串联起来和最小。

    很明显这就是一个最小生成树,不过这个题有毒。他的输入有问题。在输入m和N后面,可能有一大串的空格。就因为这个,我RE都有点懵了,要不是discuss里面有人说输入有问题,我都没注意到这个,原本只用了一个getchar吃掉最后的换行符。没想到之后还有空格。有点小坑。

    思路:这个题目如果他给你一个图,那就是最裸的prim了。不过这个题的难点也就是在他给的图你不能用Prim,你只能通过bfs去建立一个你可以新图,让这个新图去使用最小生成树。

      1 #include <string.h>
      2 #include <stdio.h>
      3 #include <queue>
      4 #define inf 0x3f3f3f
      5 #define maxn 300
      6 
      7 using namespace std;
      8 
      9 char mgraph[ maxn ][ maxn ];
     10 int bfsgraph[ maxn ][ maxn ],dist[ maxn ][ maxn ],num[ maxn ][ maxn ],ans,dis[ maxn ];
     11 bool mark[ maxn ][ maxn ],vis[ maxn ];
     12 
     13 
     14 struct note{
     15     int x,y;
     16 };
     17 
     18 void bfs(int x,int y)     //我是把图建在bfsgraph里面的。
     19 {
     20     memset( dist , 0 ,sizeof( dist ) );
     21     memset( mark , true , sizeof( mark ) );
     22     bfsgraph[ num[ x ][ y ] ][ num[ x ][ y ] ] = 0;
     23     queue<note >s;
     24     note p,q;
     25     p.x = x;
     26     p.y = y;
     27     dist[ x ][ y ] = 0;
     28     mark[ x ][ y ] = false;
     29     s.push(p);
     30     while(!s.empty())
     31     {
     32         p = s.front();
     33         s.pop();
     34         if(mark[ p.x + 1 ][ p.y ] && mgraph[ p.x + 1 ][ p.y ] != '#')
     35         {
     36             if( num[ p.x + 1 ][ p.y ]) bfsgraph[ num[ x ][ y ] ][ num[ p.x+1 ][ p.y ]] = dist[ p.x ][ p.y ] + 1;    //如果当前点为字母的话,那么把这个点与起始点的距离给记录。
     37             dist[ p.x + 1 ][ p.y ] = dist[ p.x ][ p.y ] + 1;
     38             mark[ p.x + 1 ][ p.y ] = false;
     39             q.x = p.x + 1;
     40             q.y = p.y;
     41             s.push(q);
     42         }
     43         if(mark[ p.x ][ p.y - 1 ] && mgraph[ p.x ][ p.y - 1 ] != '#')
     44         {
     45             if( num[ p.x ][ p.y - 1 ]) bfsgraph[ num[ x ][ y ] ][ num[ p.x ][ p.y - 1 ]] = dist[ p.x ][ p.y ] + 1;
     46             dist[ p.x ][ p.y - 1 ] = dist[ p.x ][ p.y ] + 1;
     47             mark[ p.x ][ p.y - 1 ] = false;
     48             q.x = p.x;
     49             q.y = p.y - 1;
     50             s.push(q);
     51         }
     52         if(mark[ p.x  ][ p.y + 1 ] && mgraph[ p.x ][ p.y + 1 ] != '#')
     53         {
     54             if( num[ p.x ][ p.y + 1 ]) bfsgraph[ num[ x ][ y ] ][ num[ p.x ][ p.y + 1 ]] = dist[ p.x ][ p.y ] + 1;
     55 
     56 
     57             dist[ p.x ][ p.y + 1 ] = dist[ p.x ][ p.y ] + 1;
     58             mark[ p.x ][ p.y + 1 ] = false;
     59             q.x = p.x;
     60             q.y = p.y + 1;
     61             s.push(q);
     62         }
     63         if(mark[ p.x - 1 ][ p.y ] && mgraph[ p.x - 1 ][ p.y ] != '#')
     64         {
     65             if( num[ p.x-1 ][ p.y ]) bfsgraph[ num[ x ][ y ] ][ num[ p.x - 1 ][ p.y ]] = dist[ p.x ][ p.y ] + 1;
     66             dist[ p.x - 1 ][ p.y ] = dist[ p.x ][ p.y ] + 1;
     67             mark[ p.x - 1 ][ p.y ] = false;
     68             q.x = p.x - 1;
     69             q.y = p.y;
     70             s.push(q);
     71         }
     72     }
     73 }
     74 int prim(int pos)
     75 {
     76    for(int i = 1; i < pos ; i++)
     77     dis[ i ] = inf ; dis[ 1 ] = 0;
     78     for(int i = 1;i < pos ; i++){
     79         int tep = inf;int k = 0;
     80         for(int j = 1 ; j < pos ; j++){
     81             if(vis[ j ]&&dis[ j ]<tep)
     82             {
     83                 tep = dis[ j ];
     84                 k = j;
     85             }
     86         }
     87         if(tep == inf) return 0;
     88         ans += tep;
     89         vis[ k ]=false;
     90         for(int j = 1 ;j < pos ; j++)
     91             if(vis[ j ]&&dis[ j ] > bfsgraph[ k ][ j ])
     92                 dis[ j ] = bfsgraph[ k ][ j ];
     93        }
     94    return 0;
     95 }
     96 
     97 
     98 
     99 int main()
    100 {
    101  //   freopen("in.txt","r",stdin);
    102     int t,m,n;
    103     char s[50];
    104     scanf("%d",&t);
    105     while( t-- )
    106     {
    107         memset( mgraph , 0 , sizeof( mgraph ) );
    108         memset( bfsgraph , 0 , sizeof( bfsgraph ) );
    109         memset( num , 0 , sizeof( num ) );
    110         scanf("%d%d",&m,&n);
    111         gets(s);          //这里要注意,要吃掉m,n后面的空格,不然就等着RE吧。
    112         ans = 0;
    113         int  pos = 1;
    114         note point[ 150 ];
    115         for( int i = 0 ; i < n ; i++ )
    116             gets(mgraph[i]);
    117         for( int i = 0 ; i < n ; i++ )
    118             for( int j = 0 ; j < m ; j++ )
    119                 if( mgraph [ i ][ j ] == 'A' || mgraph[ i ][ j ] == 'S')
    120                 {
    121                     point[ pos ].x = i;
    122                     point[ pos ].y = j;
    123                     num[ i ][ j ] = pos;     //我用num来编号,相当于一个映射,一个点集与一个数集之间的映射,因为要建图。
    124                     pos ++;
    125                 }
    126         for( int i = 1 ; i < pos ; i++ )    //对每一个点进行bfs。
    127             bfs( point[ i ].x , point[ i ].y );
    128         memset( vis , true , sizeof( vis ) );
    129         prim(pos);
    130         printf("%d
    ",ans);
    131     }
    132     return 0;
    133 }
  • 相关阅读:
    [LeetCode] Permutations II
    [LeetCode] Remove Duplicates from Sorted Array II
    [LeetCode] Permutations
    [LeetCode] Path Sum II
    [LeetCode] Plus One
    [LeetCode] Path Sum
    [LeetCode] Permutation Sequence
    [LeetCode] Pow(x, n)
    [LeetCode] Remove Duplicates from Sorted Array
    [LeetCode] Remove Element
  • 原文地址:https://www.cnblogs.com/Tree-dream/p/5744594.html
Copyright © 2011-2022 走看看