Pku2457 Part Acquisition problem1653

本文介绍了一种解决太空贸易中寻找从地球获取特定商品的最短交易路径问题的方法,使用Dijkstra算法来确定从起点到目标商品的最短路径,通过遍历节点和更新距离来找到最优解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

蒟蒻是第一次写题解,不喜勿喷,好了,先看题目:

The cows have been sent on a mission through space to acquire a new milking machine for their barn. They are flying through a cluster of stars containing N (1 <= N <= 50,000) planets, each with a trading post.
The cows have determined which of K (1 <= K <= 1,000) types of objects (numbered 1…K) each planet in the cluster desires, and which products they have to trade. No planet has developed currency, so they work under the barter system: all trades consist of each party trading exactly one object (presumably of different types).
The cows start from Earth with a canister of high quality hay (item 1), and they desire a new milking machine (item K). Help them find the best way to make a series of trades at the planets in the cluster to get item K. If this task is impossible, output -1.
给出N条边,单向的。再给出数字K.问从1号点到K点号,最短路上经过多少个点。
Input

  • Line 1: Two space-separated integers, N and K.
  • Lines 2…N+1: Line i+1 contains two space-separated integers, a_i and b_i respectively, that are planet i’s trading trading products. The planet will give item b_i in order to receive item a_i.
    Output
  • Line 1: One more than the minimum number of trades to get the milking machine which is item K (or -1 if the cows cannot obtain item K).
    Sample Input
    6 5
    1 3
    3 2
    2 3
    3 1
    2 5
    5 4
    Sample Output
    4
    ————————————————————————————————————
    题目大意就是给你n条路,边权都为1,然后n行描述哪条连哪条,然后再输出1到k的最短路经过点的个数。
    这道题的话我们就用dijkstra最短路(具体百度),而不用floyed最短路,虽然不能解释具体原因,但至少时间复杂度上要快很多,所以说到这里各位神犇想必一定有思路了,就是读入后一遍dijkstra最短路,然后点的总数也就是最短路的边数+1,因为边权都为1所以最短路的边数也就是最短路的长度。
    实在没思路也没关系,代码加注释如下:
    ps(代码很丑,确定要看吗?)

`

#include<cstdio>
#include<cstring> 
#define MAXX 10000005
using namespace std;
int n,p,pre[1005],val[1005][1005],k,adda,addb,minl;
bool point[1005];
void Dijkstra_GK_sb() 
{
	pre[1]=0; //1到自己为0.
	for(int i=2;i<=p;i++)
	{
		pre[i]=val[1][i];//1到各点的权值。
	}
	point[1]=true;//从1开始。
	for(int i=1;i<=p-1;i++)
	{
		k=1;//k=1,WA血的教训。
		minl=MAXX;
		for(int ii=1;ii<=p;ii++)
			if(!point[ii]&&pre[ii]<minl)
			{
				minl=pre[ii];
				k=ii;
			}
		    point[k]=true;//表示搜过了。
		for(int j=1;j<=p;j++)
		{
			if(!point[j]&&pre[j]>pre[k]+val[k][j])//如果到一个没搜过的点j,且1到点j的权大于1到k的权加k到j点的权。
				pre[j]=pre[k]+val[k][j];//那么走短的路。
			}
		}
	}
}
int main()
{
	scanf("%d%d",&n,&p);
	memset(point,false,sizeof(point));
	for(int i=1;i<=p;i++)
	    for(int j=1;j<=p;j++)
	    {
	    	val[i][j]=MAXX; 
		}//初始化。
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&adda,&addb);
		val[adda][addb]=1;//边权赋为1.
	}
    Dijkstra_GK_sb(); //dijkstra(请忽略GK_sb)
    if(pre[p]==MAXX)
    {
    	printf("-1\n");
	}
	else
	{
		printf("%d\n",pre[p]+1); //因为边权都为1,所以pre[p]为边数,点数也就为边数+1.
	}
	return 0;
}

——————————————————————————————————————
好了,如果代码觉得眼睛可以接受的话,那么谢谢各位神犇的观看。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值