Problem L: Pku2457 Part Acquisition
Description
给出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
//The cows possess 4 objects in total: first they trade object 1 for object 3, then object 3 for object 2, then object 2 for object 5.HINT
题目的意思是让你从1走到5;求最短路径上的点,可以先求一遍Dijkstra,用pre数组记录下它前面的数是几,再从5找它前面的数,找到则ans+1;
代码
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=1000000001;
int n,m;
int f[1005][1005],dis[1005],pre[1005];
bool is[1005];
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
memset(is,false,sizeof(is)); //在新的一轮前清空
memset(pre,0,sizeof(pre));
for(int i=1;i<=m;i++) //预处理
for(int j=1;j<=m;j++)
f[i][j]=N;
for(int i=1,a,b;i<=n;i++){
scanf("%d%d",&a,&b);
f[a][b]=1;
}
for(int i=1;i<=m;i++)
dis[i]=N;
dis[1]=0;
for(int i=1;i<=m;i++){
int k=0,minn=N;
for(int j=1;j<=m;j++)
if(!is[j]&&minn>dis[j]){
k=j;
minn=dis[j];
}
if(minn==N)break;
is[k]=true;
for(int j=1;j<=m;j++)
if(!is[j]&&dis[k]+f[k][j]<dis[j]){
dis[j]=dis[k]+f[k][j];
pre[j]=k; //记录前一个点
}
}
if(dis[m]==N) //不能历遍输出-1
printf("-1\n");
else{
int tot=pre[m],ans=2;//起点+终点=2;
while(tot!=1){ //while找点
ans++;
tot=pre[tot];
}
printf("%d\n",ans);
}
}
return 0;
}