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\n",ans);
131     }
132     return 0;
133 }
时间: 2024-08-06 07:54:20

POJ 3026(BFS+prim)的相关文章

J - Borg Maze - poj 3026(BFS+prim)

在一个迷宫里面需要把一些字母.也就是 ‘A’ 和 ‘B’连接起来,求出来最短的连接方式需要多长,也就是最小生成树,地图需要预处理一下,用BFS先求出来两点间的最短距离, ********************************************************************************** #include<algorithm>#include<stdio.h>#include<string.h>#include<que

POJ 2485-Highways(最小生成树prim)

Highways Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 22433   Accepted: 10341 Description The island nation of Flatopia is perfectly flat. Unfortunately, Flatopia has no public highways. So the traffic is difficult in Flatopia. The Fl

poj3026(bfs+prim)

The Borg is an immensely powerful race of enhanced humanoids from the delta quadrant of the galaxy. The Borg collective is the term used to describe the group consciousness of the Borg civilization. Each Borg individual is linked to the collective by

POJ 3278 Catch That Cow(BFS 剪枝)

题目链接:http://poj.org/problem?id=3278 这几次都是每天的第一道题都挺顺利,然后第二道题一卡一天. = =,今天的这道题7点40就出来了,不知道第二道题在下午7点能不能出来.0 0 先说说这道题目,大意是有个农夫要抓牛,已知牛的坐标,和农夫位置.而且农夫有三种移动方式,X + 1,X - 1,X * 2,问最少几步抓到牛. 开始认为很简单的,三方向的BFS就能顺利解决,然后在忘开标记的情况下直接广搜,果然TLE,在你计算出最少位置之前,牛早跑了. 然后反应过来开标记

poj 1724ROADS(bfs和dfs做法)

1 /* 2 dfs比较好想,就是测试数据的问题,导致在遍历边的时候要倒着遍历才过! 3 */ 4 #include<iostream> 5 #include<cstdio> 6 #include<cstring> 7 #include<vector> 8 #include<algorithm> 9 #define Max 0x3f3f3f3f 10 using namespace std; 11 12 struct node{ 13 int D

poj 1258 Agri-Net (最小生成树 prim)

Agri-Net Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 39499   Accepted: 16017 Description Farmer John has been elected mayor of his town! One of his campaign promises was to bring internet connectivity to all farms in the area. He nee

poj 1915 Knight Moves (bfs搜索)

Knight Moves Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 21919   Accepted: 10223 Description Background Mr Somurolov, fabulous chess-gamer indeed, asserts that no one else but him can move knights from one position to another so fast

Mondriaan&#39;s Dream - POJ 2411(状态压缩)

题目大意:有一些1*2的矩形,现在用这些小矩形覆盖M*N的大矩形,不能重复覆盖,并且要覆盖完全,求有多少种覆盖方式. 分析:可以使用1和0两种状态来表示这个位置有没有放置,1表示放置,0表示没有放置,可以有三种放置方式. 一,竖着放. 二,不放.三,横着放.直接DFS这些情况就行了................还是递归容易理解. 代码如下: =============================================================================

Poj 1328(雷达安装)几何+贪心

[题目描述]: 给定n个小岛以及这些小岛的位置,并输入雷达的辐射面积,问最少需要多少个雷达站才能覆盖所有小岛? [思路分析]: 本题首先想到的是运用贪心算法,但是算法想到了如何贪心?这道题我自己开始做之时只有一点思路,就是让每一个雷达覆盖较多的点,但是如何较多覆盖,这就是典型的数学问题了,自己没有思索出来,最后在网上看了题解才明白如何做.下面我们看看如何建图: 我们通过这个图首先运用了一个数学知识,就是以小岛为圆心,雷达辐射范围为圆心建立一个圆,该圆与x轴有一个交点,以该交点作为雷达站铺设点那么