http://acm.hdu.edu.cn/showproblem.php?pid=4435
bfs搜索
大致题意是 给出N个点,让你选择性地建立加油站,在第i个点建立加油站的费用为2^i-1,要使自己能从1号点经过所有点回到原点,
点可以重复经过,加油费用不计,每次加油最多能跑的距离为D。输出的答案是2进制,由费用10进制转化过来就是在第i个点建立加
油站,答案从右往左数第i个值就为1。
第一步判断所有点都建立加油站能不能完成题目的要求,不能输出-1。
能完成要求的话,我们注意到建站费用是和点的编号有关的,比如第i个点建站的费用是等于前i-1个点都建站的费用+1,二进制的规律。
然后我们可以从后往前判断当前加油站能不能拆。
dist数组存从当前点到最近的加油站的距离,判断分两个方面:
如果当前点也有加油站,dist[i] <= D就可以;
如果当前点决定不建立加油站,那么dist[i]要小于D/2;
不符合要求就不能拆这个加油站。
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "math.h"
#include "algorithm"
#include "iostream"
#include "queue"
#include "string.h"
using namespace std;
#define maxn 1005
#define INF 1000000000
int sta[ maxn ] ;
double dist[ maxn ] ;
struct node
{
int x , y ;
}edge[ maxn ] ;
int num[ maxn ][ maxn ] ;
int used[ maxn ] ;
int n , m ;
double path( int x , int y )
{
return sqrt( (edge[ x ].x - edge[ y ].x ) * ( edge[ x ].x - edge[ y ].x ) + ( edge[ x ].y - edge[ y ].y )*( edge[ x ].y - edge[ y ].y ) ) ;
}
int bfs()
{
queue<int> Q ;
memset( used , 0 ,sizeof( used ) ) ;
for( int i = 0 ; i < n ; i++ )
{
if( !sta[ i ] )
dist[ i ] = INF ;
else
dist[ i ] = 0 ;
}
dist[ 0 ] = 0 ;
used[ 0 ] = 1 ;
Q.push( 0 ) ;
while( !Q.empty() )
{
int u = Q.front() ;
Q.pop() ;
for( int i = 0 ; i < n ; i++ )
{
if( !used[ i ] && num[ u ][ i ] <= m )
{
dist[ i ] = min( dist[ i ] , dist[ u ] + num[ u ][ i ] ) ;
if( sta[ i ] )
{
used[ i ] = 1 ;
Q.push( i ) ;
}
}
}
}
for( int i = 0 ; i < n ; i++ )
{
if( sta[ i ] && !used[ i ] )
return 0 ;
else if( !sta[ i ] && dist[ i ] * 2 > m )
return 0 ;
}
return 1;
}
void solved()
{
for( int i = 0 ; i < n ; i++ )
sta[ i ] = 1 ;
if( !bfs() )
{
puts("-1");
return ;
}
for( int i = n - 1 ; i >= 1 ; i-- )
{
sta[ i ] = 0 ;
if( bfs() )
continue ;
sta[ i ] = 1;
}
int temp = n - 1 ;
while( !sta[ temp ] )
temp-- ;
for( int i = temp ; i >= 0 ; i-- )
printf( "%d" , sta[ i ] ) ;
printf( "\n" ) ;
}
int main()
{
while( ~scanf( "%d%d" ,&n , &m ) )
{
for( int i = 0 ; i < n ; i++ )
{
scanf( "%d%d" ,&edge[ i ].x , &edge[ i ].y ) ;
}
for( int i = 0 ; i < n ; i++ )
for( int j = 0 ; j < n ; j++ )
{
num[ i ][ j ] = (int)ceil(path( i , j )) ;
}
solved();
}
return 0;
}
题解参照 http://www.cnblogs.com/rainydays/archive/2012/10/27/2742037.html