蒟蒻是第一次写题解,不喜勿喷,好了,先看题目:
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;
}
——————————————————————————————————————
好了,如果代码觉得眼睛可以接受的话,那么谢谢各位神犇的观看。