题意:给出N个正常的机器人,还有一个感染病毒的机器人,从这台机器人开始传播病毒,当传染到一个机器人,这个机器人也开始加入传播的行列,向其他正常的机器人传播,问最少的时间。
解题过程:这题说难其实不难,也很容易就能想到用最小生成树,就是对BFS搜索算法的不熟,导致在建立连接的时候有些麻烦。这题先用BFS计算出任意两点之间的距离,然后用prim算最小生成树就行了。
代码:
View Code
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> #include <algorithm> #include <queue> #include <math.h> #define N 105 #define INF 1000000000 using namespace std ; struct node { int x , y ; }dir[4] = {{-1,0} ,{1,0} , {0,1},{0,-1}} ; int p[N][N] , map[N][N] , vist[N][N] ; int n , m , num , d[N][N] ; void bfs( int sx , int sy ) { node st , u , v ; int xi , yi ; queue<node>q ; st.x = sx ; st.y = sy ; memset( vist , 0 , sizeof ( vist )) ; d[sx][sy] = 0 ; q.push( st ) ; vist[sx][sy] = 1 ; while ( !q.empty()) { u = q.front(); q.pop(); //如果p[u.x][u.y]>0时说明这个地方时机器人,然后建立连接。 if ( p[u.x][u.y] ) { map[p[sx][sy]][p[u.x][u.y]] = d[u.x][u.y] ; } for ( int i = 0 ; i < 4 ; i++ ) { xi = u.x + dir[i].x ; yi = u.y + dir[i].y ; if ( xi > 0 && xi <= m && yi > 0 && yi <= n && !vist[xi][yi] && p[xi][yi] >= 0 ) { vist[xi][yi] = 1 ; d[xi][yi] = d[u.x][u.y] + 1 ; v.x = xi ; v.y = yi ; q.push( v ) ; } } } } //prim求最小生成树 void prim() { int dis[N] , mark[N] ; int min_t , i , j ,pos ; int sum = 0 ; for ( i = 1 ; i < num ; i++ ) { dis[i] = map[1][i] ; mark[i] = 0 ; } mark[1] = 1 ; for ( i = 1 ; i < num - 1; i++ ) { min_t = INF ; for ( j = 1 ; j < num ; j++ ) { if ( !mark[j] && dis[j] < min_t ) { min_t = dis[j] ; pos = j ; } } mark[pos] = 1 ; sum += min_t ; for ( j = 1 ; j < num ; j++ ) if ( !mark[j] && dis[j] > map[pos][j] ) dis[j] = map[pos][j] ; } printf ( "%d\n" , sum ) ; } int main() { int cas , i , j ; char str[N] ; //freopen( "input.txt" , "r" , stdin) ; scanf ( "%d" , &cas ) ; while ( cas-- ) { scanf ( "%d%d" , &m , &n ) ; gets( str ) ; memset( p , 0 , sizeof ( p )) ; num = 1 ; for ( i = 1 ; i <= n ; i++ ) { gets( str ) ; for ( j = 1 ; j <= m ; j++ ) { if ( str[j-1] == '#' ) p[i][j] = -1 ; else if ( str[j-1] == 'A' || str[j-1] == 'S' ) { p[i][j] = num++ ; } } } //求任意一点到其他各点的距离 for ( i = 1 ; i <= n ; i++ ) for ( j = 1 ; j <= m ; j++ ) if ( p[i][j] > 0 ) bfs( i , j ) ; /*cout<<num<<endl ; for ( i = 1 ; i < num ; i++ ) { for ( j = 1 ; j < num ; j++ ) if ( map[i][j] ) printf ( "%d %d : %d\n" , i , j , map[i][j] ); }*/ prim(); } return 0 ; }