建立判断hdu4435chargestation

查了好多资料,发现还是不全,干脆自己整理吧,至少保证在我的做法正确的,以免误导读者,也是给自己做个记录吧!

    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

文章结束给大家分享下程序员的一些笑话语录: 一程序员告老还乡,想安度晚年,于是决定在书法上有所造诣。省略数字……,准备好文房4宝,挥起毛笔在白纸上郑重的写下:Hello World

原文地址:https://www.cnblogs.com/xinyuyuanm/p/3091525.html