poj 3126 (最短路)

题意:更改四位数的门牌号(素数),每次只能改一个数字,问最少多少次能改到目标数字。

思路:打表出四位的所有素数,然后建图,只有一个位数的数字不同的连边,跑最短路,,,






#include<iostream>
#include<stdio.h>
#include<queue>
#include<string.h>
const int N=10000;
const int inf=0x3fffffff;
using namespace std;
int link[N],prim[N],dis[N],vis[N];
struct edge
{
	int st,ed,next;
}e[N*10];
int head[N],num;
void addedge(int x,int y)
{
	e[num].st=x;e[num].ed=y;e[num].next=head[x];head[x]=num++;
	e[num].st=y;e[num].ed=x;e[num].next=head[y];head[y]=num++;
}
bool judge(int x,int y)
{
	int sum=0;
	while(x)
	{
		if(x%10!=y%10)
			sum++;
		x/=10;y/=10;
	}
	if(sum==1)
		return true;
	return false;
}
int spfa(int s,int ed)
{
	queue<int>Q;
	int i,v,u;
	for(i=1000;i<=9999;i++)
	{
		vis[i]=0;dis[i]=inf;
	}
	dis[s]=0;vis[s]=1;
	Q.push(s);
	while(!Q.empty())
	{
		u=Q.front();
		Q.pop();
		vis[u]=0;
		if(u==ed)break;
		for(i=head[u];i!=-1;i=e[i].next)
		{
			v=e[i].ed;
			if(dis[v]>dis[u]+1)
			{
				dis[v]=dis[u]+1;
				if(vis[v]==0)
				{
					Q.push(v);
					vis[v]=1;
				}
			}
		}
		
	}
	return dis[ed];
}
int main()
{
	int i,j,k,t,a,b;
	k=0;
	for(i=2;i<N;i++)
	{
		if(link[i]==1)continue;
		for(j=i+i;j<N;j+=i)	link[j]=1;
		if(i>999)
		prim[k++]=i;
	}
	memset(head,-1,sizeof(head));
	num=0;
	for(i=0;i<k;i++)
	{
		for(j=i+1;j<k;j++)
			if(judge(prim[i],prim[j]))
				addedge(prim[i],prim[j]);
	}
    scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&a,&b);
		printf("%d\n",spfa(a,b));
	}
	return 0;
}

点赞