poj 3026 Borg Maze

题意:给出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 ;
}
posted @ 2012-10-25 16:12  Misty_1  阅读(147)  评论(0编辑  收藏  举报