标签:uid ati ever for searching 顶点 sub lines ber
Description
Input
Output
Sample Input
2 6 5 ##### #A#A## # # A# #S ## ##### 7 7 ##### #AAA### # A# # S ### # # #AAA### #####
Sample Output
8 11
先大致翻译一遍:在一个地图中,S要去到达每一个A,而S从一开始就可以分开各自去到达A,求出S到达每个A的总的最小步数。
题意:读入一个字符矩阵,求出联通所有A和S的最小生成树权值,S只有一个。
思路:读入字符图str,将字符图中的所有A和S进行编号(不用管S编号是否为1,因为用最小生成树计算最小路径权值会到达每一个顶点),遍历字符图,遇到A或S就进行BFS,BFS过程中,如果遇到A或S,就将步数存入
一个map图(存编号路径的权值),最后套用prime模板,输出。
注意:1.读入的时候,有n多空格的数据出现,不能用%c进行读,正解是gets
2.BFS时注意搜索除了#以外的所有顶点
~~~~这道题自己写了两天,因为用一个比较耗时的方法去写,一直tle,但是自己始终觉得可以优化,最后还是tle~~后来小伙伴也A了这道题,就借鉴了他的思路。
我是的tle思路(hhh 奇怪的思路)是将每个编号顶点都进行遍历查找,而小伙伴的方法是遇到一个编号顶点就整张图进行遍历,只要在遍历过程中遇到了满足要求的点就存入,大大降低查找时间,真是一个悲伤的tle~~
#include<stdio.h> #include<queue> #include<iostream> #include<string.h> using namespace std; #define inf 0x3f3f3f3f #define N 155 int map[N][N],book[55][55],e[55][55]; char str[55][55];//存储字符图 int n,m,sum,count1; int k[4][2]={0,1,0,-1,1,0,-1,0}; struct node{ int x,y,step; }; int BFS(int sx,int sy,int sn) { int en,x,y,nx,ny,i; node start,tail,head; memset(book,0,sizeof(book));//每次查找图都要进行清空 queue<node>Q; start.step = 0; start.x = sx; start.y = sy; Q.push(start); while(!Q.empty()) { head = Q.front(); Q.pop(); for(i = 0; i < 4; i ++) { tail.x = head.x + k[i][0]; tail.y = head.y + k[i][1]; if(tail.x < 0||tail.x > n-1||tail.y < 0||tail.y > m-1) continue; if(!book[tail.x][tail.y]&&str[tail.x][tail.y]!=‘#‘) { book[tail.x][tail.y] = 1; tail.step = head.step+ 1; Q.push(tail); if(str[tail.x][tail.y] == ‘A‘||str[tail.x][tail.y] == ‘S‘) {//遇到符合条件的点就将起点到终点编号的权值存入map图 en = e[tail.x][tail.y]; map[sn][en] = tail.step; } } } } } void Getmap() { int i,j; count1 = 0; memset(e,0,sizeof(e)); for(i = 0; i < n; i ++) for(j = 0; j < m; j ++) if((str[i][j]==‘A‘||str[i][j] == ‘S‘)) { e[i][j] = ++count1;//对符合条件的字符进行编号 } for(i = 0; i < n; i ++) for(j = 0; j < m; j ++) { if(str[i][j] == ‘A‘||str[i][j] == ‘S‘)//遇到符合条件的字符就进行BFS { BFS(i,j,e[i][j]); } } } int Prime()//prime模板 { int i,j,u,dis[N],flag[N],min; memset(flag,0,sizeof(flag)); sum = 0; flag[1] = 1; for(i = 1; i <= count1; i ++) dis[i] = map[1][i]; for(i = 1; i < count1; i ++) { min = inf; for(j = 1; j <= count1; j ++) if(!flag[j]&&dis[j] < min) { min = dis[j]; u = j; } flag[u] = 1; sum += dis[u]; for(j = 1; j <= count1; j ++) if(!flag[j]&&dis[j] > map[u][j]) dis[j] = map[u][j]; } return sum; } int main() { int t,i,j; scanf("%d",&t); while(t --) { scanf("%d%d",&m,&n); gets(str[0]); for(i = 0; i < n; i ++)//读图一定注意,坑~~ gets(str[i]); Getmap();//建图 printf("%d\n",Prime());//输出最小生成树权值 } return 0; }
【练习赛补题】poj 3026 Borg Maze 【bfs+最小生成树】【坑~】
标签:uid ati ever for searching 顶点 sub lines ber
原文地址:http://www.cnblogs.com/chengdongni/p/7395775.html