POJ 3126 水 图

8 篇文章 0 订阅

素数表

离散化

建图


#include "stdio.h"
#include "string.h"
#include "math.h"
#include "stdlib.h"
int prime[10010],data[10010];
int n,end,start;
int map[2010][2010],dis[10010];

void make_map(int w)
{
	int i,s;
	for (i=0;i<=9;i++)
	{
		s=i+w/10*10;
		if (s==w) map[data[s]][data[w]]=map[data[w]][data[s]]=0;
		else 
			if (s!=w && prime[s]==0)
				map[data[s]][data[w]]=map[data[w]][data[s]]=1;
	}

	for (i=0;i<=9;i++)
	{
		s=w%10+w/100*100+i*10;
		if (s==w) map[data[s]][data[w]]=map[data[w]][data[s]]=0;
		else 
			if (s!=w && prime[s]==0)
				map[data[s]][data[w]]=map[data[w]][data[s]]=1;
	}

	for (i=0;i<=9;i++)
	{
		s=w%100+w/1000*1000+i*100;
		if (s==w) map[data[s]][data[w]]=map[data[w]][data[s]]=0;
		else 
			if (s!=w && prime[s]==0)
				map[data[s]][data[w]]=map[data[w]][data[s]]=1;
	}

	for (i=1;i<=9;i++)
	{
		s=w%1000+i*1000;
		if (s==w) map[data[s]][data[w]]=map[data[w]][data[s]]=0;
		else 
			if (s!=w && prime[s]==0)
				map[data[s]][data[w]]=map[data[w]][data[s]]=1;
	}

}

void make()
{
	int hash[2010];
	int a,b,min,i,k;
    int time;
	time=1061;
	memset(hash,0,sizeof(hash));
	a=data[start];
	b=data[end];
	hash[a]==1;
	dis[a]=0;
	while (time--)
	{
		min=99999999;
		for (i=1;i<=1061;i++)
			if (dis[i]<min  && hash[i]==0)
			{
				min=dis[i];
				k=i;
			}

		if (min==99999999) return ;
		

		if (k==b) return ;

		hash[k]=1;

		for (i=1;i<=1061;i++)
			if (hash[i]==0 && k!=i &&  dis[k]+map[k][i]<dis[i])
				dis[i]=dis[k]+map[k][i];
	}
}


int main()
{
	int Case,i,j;
	memset(prime,0,sizeof(prime));
	prime[1]=1;
	n=0;
	for (i=2;i<10000;i++)
		if (prime[i]==0)
		{
			if (i>=1000)
			{
				n++;
				data[i]=n;
			}

			for (j=i+i;j<10000;j+=i)
				prime[j]=1;
		}

	// printf("%d\n",n); n=1061;

	n=1061;
	for (i=1;i<=1061;i++)
		for (j=i;j<=1061;j++)
			map[i][j]=map[j][i]=99999999;

	for (i=1000;i<10000;i++)
		if (prime[i]==0)
			make_map(i);

	scanf("%d",&Case);
	while (Case--)
	{
		n=1061;
		for (i=1;i<=1061;i++)
			dis[i]=99999999;
		scanf("%d%d",&start,&end);
		if (start==end)
		{
			printf("0\n");
			continue;
		}
	
		make();

	
		printf("%d\n",dis[data[end]]);
	}
	return 0;



}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值