Part Acquisition--(最短路径,Dijkstra)

来源:互联网 发布:js中判断字符串长度 编辑:程序博客网 时间:2024/06/06 05:49

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.
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). 

* Lines 2..T+1: The ordered list of the objects that the cows possess in the sequence of trades.
Sample Input
6 51 33 22 33 12 55 4
Sample Output
41325
Hint
OUTPUT DETAILS: 

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.

题意:有n个交换点,k种物品,每个交换点对应a,b两个数表示可在此交换点用a换到b,问用1物品最少几次可以换到k物品,并输出路径

先想到是最短路径问题,用Dijktra来求,并最终判断是否能换到

代码:

#include<iostream>#include<string>#include<cstdio>#include<algorithm>#include<cmath>#include<iomanip>#include<queue>#include<cstring>#include<map>using namespace std;typedef long long ll;#define pi acos(-1.0)#define inf 0x3f3f3f#define M 1005int n,k,s,e;int a[50001][1001],num[M],dis[M],pre[M]; //a数组存放点的关系,num[i]是以第i个点为起点的边的个数,bool ok[M];      //dis[i]是点i到1点的最少步数,pre[i]存放点的前驱节点void print(int i){    if(pre[i]!=0) print(pre[i]);    printf("%d\n",i);}int main(){    int i,j,t;    scanf("%d%d",&n,&k);    for(i=1;i<=n;i++)    {        scanf("%d%d",&s,&e);        a[s][num[s]++]=e;   //点s的第num[s]条边的终点是e    }    memset(dis,127/3,sizeof(dis));    memset(ok,false,sizeof(ok));    dis[1]=1; pre[1]=0;    for(i=1;i<=k-1;i++)    {        t=0;        for(j=1;j<=k;j++)            if(!ok[j]&&dis[j]<dis[t])                t=j;        //cout<<t<<endl;        if(t==0) break;        ok[t]=true;        for(j=0;j<num[t];j++)        {            if(dis[t]+1<dis[a[t][j]])            {                dis[a[t][j]]=dis[t]+1;                pre[a[t][j]]=t;            }        }    }    if(dis[k]<k*2) {printf("%d\n",dis[k]); print(k);}    else {printf("-1\n");return 0;}    return 0;}


原创粉丝点击