寒假回家还是学了很多知识的,巩固了之前自己一直不常熟练的图论的一些算法,搜索算法,最短路算法和生成树算法,感觉还是有很大的收获,但是发现一些问题,首先,自己对于数据结构上的问题还是很生疏,例如处理大规模的图结构的时候对于邻接表的书写还是很陌生,需要学习的地方,还有就是很多算法的优化都要用到数据结构中的知识,所以回到学校要赶快学习数据结构的了。第二,虽然自己书写算法的思路有一定的清晰度了,但是对于代码的长度却很纠结,一个STL的BFS居然都能写到4000B+,不晓得是怎么回事的了,多看看别人的代码,看看别人是怎么提高代码的效率的。回到学校了以后,除了学习数据结构以外,补上关于求前连通分量,图匹配的问题。图论想先放一放的了,多看看书,有空的时候切切题,下学期空闲的时候比较多,应该可以切多点题的吧。
回学校前的最后一晚上写了一道题,又是4000B+。。。。MST+PRIM(POJ3026)同化所有的外星人,看成一堆人去同化外星人,同化了外星人后分开去同化其他的外星人,就是求所有节点的MST的权值。自己的代码跑了43MS,应该还可以得到优化,在求解DIS数组的时候,可以降低复杂度,毕竟这个矩阵是个对称阵的,剩下自己也没想的了,加上一个判断就可以解决的了。
代码
//MST+BFS 要是不看DISSCUSS 估计又是WA。。。
#include<iostream>
#include<queue>
using namespace std ;
typedef struct node_p{
int x0 , y0 , step ;
}node ;
const int maxn = 55 ;
const int maxm = 105 ;
const int INF = 1000000000 ;
char temp[10000] ;
int map[maxn][maxn] , dis[maxm][maxm] , d[maxm] , d_flag[maxm] ;
int x , y ; //x__col y__row
node cur_node ,de_node;
int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
void BFS( int cur_x , int cur_y ,int count ){
int p_num , flag[maxn][maxn] ;
queue<node>q ;
memset(flag , 0 , sizeof(flag)) ;
p_num = 0 ;
cur_node.x0 = cur_x ;
cur_node.y0 = cur_y ;
cur_node.step = 0 ;
flag[cur_x][cur_y] = 1 ;
q.push(cur_node) ; // start-point pushed
while(!q.empty()){
cur_node = q.front() ;
q.pop() ;
/*printf("cur_node.x0 == %d ",cur_node.x0);
printf("cur_node.y0 == %d ",cur_node.y0);
printf("cur_node.step == %d\n ",cur_node.step);*/
if( map[cur_node.x0][cur_node.y0] != 0 && map[cur_node.x0][cur_node.y0] != -1 ){
dis[map[cur_x][cur_y]][map[cur_node.x0][cur_node.y0]] = cur_node.step ;
dis[map[cur_node.x0][cur_node.y0]][map[cur_x][cur_y]] = cur_node.step ;
p_num ++ ;
if(count == p_num)
break ;
}
//update
for( int i = 0 ; i < 4 ; i++ ){
int px , py ;
px = cur_node.x0 + dir[i][0] ;
py = cur_node.y0 + dir[i][1] ;
if(flag[px][py] == 0
&& px>=0 && px<y
&& py>=0 && py<x
&& map[px][py] != 0 ){
de_node.x0 = px ;
de_node.y0 = py ;
de_node.step = cur_node.step + 1 ;
flag[px][py] = 1 ;
q.push(de_node) ;
}
}
}
}
int main(){
int T , i , j , count ;
scanf("%d",&T) ;
while( T-- ){
scanf("%d%d",&x,&y) ;
gets(temp) ; //for useless space_char
memset(map , 0 , sizeof(map)) ;
memset(d_flag , 0 , sizeof(d_flag)) ;
count = 0 ;
for( i = 0 ; i < y ; i++ ){
gets(temp);
for( j = 0 ; j < x ; j++ ){
if(temp[j] == '#')
map[i][j] = 0 ;
else if(temp[j] == ' ')
map[i][j] = -1 ;
else if(temp[j] == 'A'||temp[j] == 'S'){
count ++ ;
map[i][j] = count ;
}
}
}
//BFS to get_dis
for( i = 0 ; i < count ; i++ ){
for( j = 0 ; j < count ; j++ ){
dis[i][j] = INF ;
}
}
for( i = 0 ; i < y ; i++ ){
for( j = 0 ; j < x ; j++){
if(map[i][j] != 0 && map[i][j] != -1 )
BFS(i , j , count) ;
}
}
//debug..
/*for( i = 1 ; i <= count ; i++ ){
for( j = 1 ; j <= count ; j++ ){
printf("%d ", dis[i][j]);
}
printf("\n");
}*/
//prim to get MST_ans ;
int ans ;
ans = 0 ;
d_flag[1] = 1 ;
for( i = 1 ; i <= count ; i++ )
d[i] = dis[1][i] ;
for( i = 2 ; i <= count ; i++ ){
int min_node = 0 ;
int minlen = INF ;
for( j = 1 ; j <= count ; j++ ){
if( minlen > d[j] && d_flag[j] == 0 ){
min_node = j ;
minlen = d[j] ;
}
}
if(min_node != 0 ){
//printf("minlen = %d\n",minlen) ;
d_flag[min_node] = 1 ;
ans += minlen ;
//printf("ans = %d\n" , ans) ;
for( j = 1 ; j <= count ; j++ ){
if(d[j]>dis[min_node][j])
d[j] = dis[min_node][j] ;
}
}
else break ;
}
printf("%d\n",ans) ;
}
return 0;
}
#include<iostream>
#include<queue>
using namespace std ;
typedef struct node_p{
int x0 , y0 , step ;
}node ;
const int maxn = 55 ;
const int maxm = 105 ;
const int INF = 1000000000 ;
char temp[10000] ;
int map[maxn][maxn] , dis[maxm][maxm] , d[maxm] , d_flag[maxm] ;
int x , y ; //x__col y__row
node cur_node ,de_node;
int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
void BFS( int cur_x , int cur_y ,int count ){
int p_num , flag[maxn][maxn] ;
queue<node>q ;
memset(flag , 0 , sizeof(flag)) ;
p_num = 0 ;
cur_node.x0 = cur_x ;
cur_node.y0 = cur_y ;
cur_node.step = 0 ;
flag[cur_x][cur_y] = 1 ;
q.push(cur_node) ; // start-point pushed
while(!q.empty()){
cur_node = q.front() ;
q.pop() ;
/*printf("cur_node.x0 == %d ",cur_node.x0);
printf("cur_node.y0 == %d ",cur_node.y0);
printf("cur_node.step == %d\n ",cur_node.step);*/
if( map[cur_node.x0][cur_node.y0] != 0 && map[cur_node.x0][cur_node.y0] != -1 ){
dis[map[cur_x][cur_y]][map[cur_node.x0][cur_node.y0]] = cur_node.step ;
dis[map[cur_node.x0][cur_node.y0]][map[cur_x][cur_y]] = cur_node.step ;
p_num ++ ;
if(count == p_num)
break ;
}
//update
for( int i = 0 ; i < 4 ; i++ ){
int px , py ;
px = cur_node.x0 + dir[i][0] ;
py = cur_node.y0 + dir[i][1] ;
if(flag[px][py] == 0
&& px>=0 && px<y
&& py>=0 && py<x
&& map[px][py] != 0 ){
de_node.x0 = px ;
de_node.y0 = py ;
de_node.step = cur_node.step + 1 ;
flag[px][py] = 1 ;
q.push(de_node) ;
}
}
}
}
int main(){
int T , i , j , count ;
scanf("%d",&T) ;
while( T-- ){
scanf("%d%d",&x,&y) ;
gets(temp) ; //for useless space_char
memset(map , 0 , sizeof(map)) ;
memset(d_flag , 0 , sizeof(d_flag)) ;
count = 0 ;
for( i = 0 ; i < y ; i++ ){
gets(temp);
for( j = 0 ; j < x ; j++ ){
if(temp[j] == '#')
map[i][j] = 0 ;
else if(temp[j] == ' ')
map[i][j] = -1 ;
else if(temp[j] == 'A'||temp[j] == 'S'){
count ++ ;
map[i][j] = count ;
}
}
}
//BFS to get_dis
for( i = 0 ; i < count ; i++ ){
for( j = 0 ; j < count ; j++ ){
dis[i][j] = INF ;
}
}
for( i = 0 ; i < y ; i++ ){
for( j = 0 ; j < x ; j++){
if(map[i][j] != 0 && map[i][j] != -1 )
BFS(i , j , count) ;
}
}
//debug..
/*for( i = 1 ; i <= count ; i++ ){
for( j = 1 ; j <= count ; j++ ){
printf("%d ", dis[i][j]);
}
printf("\n");
}*/
//prim to get MST_ans ;
int ans ;
ans = 0 ;
d_flag[1] = 1 ;
for( i = 1 ; i <= count ; i++ )
d[i] = dis[1][i] ;
for( i = 2 ; i <= count ; i++ ){
int min_node = 0 ;
int minlen = INF ;
for( j = 1 ; j <= count ; j++ ){
if( minlen > d[j] && d_flag[j] == 0 ){
min_node = j ;
minlen = d[j] ;
}
}
if(min_node != 0 ){
//printf("minlen = %d\n",minlen) ;
d_flag[min_node] = 1 ;
ans += minlen ;
//printf("ans = %d\n" , ans) ;
for( j = 1 ; j <= count ; j++ ){
if(d[j]>dis[min_node][j])
d[j] = dis[min_node][j] ;
}
}
else break ;
}
printf("%d\n",ans) ;
}
return 0;
}
