建立判断hdu4435-charge-station

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

    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

你可能感兴趣的:(char)