Part Acquisition
Time Limit: 1000MS | Memory Limit: 65536K | |||
Total Submissions: 3709 | Accepted: 1599 | Special Judge |
Description
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.
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.
* 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.
* Lines 2..T+1: The ordered list of the objects that the cows possess in the sequence of trades.
Sample Input
6 5 1 3 3 2 2 3 3 1 2 5 5 4
Sample Output
4 1 3 2 5
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.
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.
Source
/******************************
*
* acm: poj-2457
*
* title: Part Acquisition
*
* time : 2014.8.28
*
*******************************/
/*
题意:
奶牛身上有物品1,现在他们要换成物品k,现在给出一张有向图,i指向j表示可以用i换j,
问最少要几次才可以换到需要的物品;如果换不到,输出-1。
输入输出:
第一行输入N(可换的物品条目 即路径总数)和K(物品数量)
接下来N行表示每行2个变量,第一个变量(物品)可以换到第二个变量(物品)。
如果换得到则输出次数,并输出路径,否则-1.
思路:
求1->k的最短路径,并记录最短路径。 本题用Dijkstra算法
第一个物品到第二个物品路径设为1,否则为无穷大
*/
/*
测试用例 1 2 1 2 => 2 1 2
1 3 2 3 => -1
*/
#include <stdio.h>
#include <stdlib.h>
#define MAXVEX 1001
#define MAXEDGE 50001
#define INFINITY 100000
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef struct EdgeNode
{
int adjvex;
int weight;
struct EdgeNode *next;
} EdgeNode;
typedef struct VertexNode
{
// int data;
EdgeNode *firstedge;
}VertexNode, AdjList[MAXVEX];
typedef struct graphAdjList
{
AdjList adjList;
int numVertexes;
int numEdges; //图中当前顶点数和边数
} graphAdjList, *GraphAdjList;
//创建邻接表
void CreateALGraph(GraphAdjList GL, int n, int k)
{
int i, j;
int t;
EdgeNode *e;
GL->numVertexes = k;
GL->numEdges = n;
for (i = 1; i <= GL->numVertexes; i++)
{
GL->adjList[i].firstedge = NULL;
}
for (t = 1; t <= GL->numEdges; t++)
{
scanf("%d%d", &i, &j);
e = (EdgeNode *)malloc(sizeof(EdgeNode));
e->adjvex = j;
e->weight = 1;
e->next = GL->adjList[i].firstedge;
GL->adjList[i].firstedge = e;
}
/* 静态数据
GL->numVertexes = 5;
GL->numEdges = 6;
e = (EdgeNode *)malloc(sizeof(EdgeNode));
e->adjvex = 3;
e->weight = 1;
e->next = GL->adjList[1].firstedge;
GL->adjList[1].firstedge = e;
e = (EdgeNode *)malloc(sizeof(EdgeNode));
e->adjvex = 2;
e->weight = 1;
e->next = GL->adjList[3].firstedge;
GL->adjList[3].firstedge = e;
e = (EdgeNode *)malloc(sizeof(EdgeNode));
e->adjvex = 3;
e->weight = 1;
e->next = GL->adjList[2].firstedge;
GL->adjList[2].firstedge = e;
e = (EdgeNode *)malloc(sizeof(EdgeNode));
e->adjvex = 1;
e->weight = 1;
e->next = GL->adjList[3].firstedge;
GL->adjList[3].firstedge = e;
e = (EdgeNode *)malloc(sizeof(EdgeNode));
e->adjvex = 5;
e->weight = 1;
e->next = GL->adjList[2].firstedge;
GL->adjList[2].firstedge = e;
e = (EdgeNode *)malloc(sizeof(EdgeNode));
e->adjvex = 4;
e->weight = 1;
e->next = GL->adjList[5].firstedge;
GL->adjList[5].firstedge = e;
/* int i;
for (i = 1; i <= 5; i++)
printf("%d ", P[i]);
-1 3 -1 5 2
1 2 3 4 5
*/
}
typedef int Patharc[MAXVEX];
typedef int ShortPathTable[MAXVEX];
//邻接表 Dijkstra算法 + 并查集
Status ShortestPath_Dijkstra(graphAdjList GL, int v0, Patharc P)
{
int uniun_Eq(ShortPathTable D, int start, int end);
int v, w, k, min;
int final[MAXVEX] = {0};
ShortPathTable D;
EdgeNode *e;
for (v = 1; v <= GL.numVertexes; v++)
{
D[v] = INFINITY;
P[v] = -1;
}
e = GL.adjList[v0].firstedge;
if (e == NULL)
{
return FALSE;
}
while (e != NULL)
{
D[e->adjvex] = e->weight;
P[e->adjvex] = v0;
e = e->next;
}
final[v0] = 1;
for (v = 2; v <= GL.numVertexes; v++)
{
min = INFINITY;
for (w = 1; w <= GL.numVertexes; w++)
{
if (!final[w] && D[w] < min)
{
k = w;
min = D[w];
}
}
final[k] = 1;
e = GL.adjList[k].firstedge;
while (e != NULL)
{
if (!final[e->adjvex] && min + e->weight < D[e->adjvex])
{
D[e->adjvex] = min + e->weight;
P[e->adjvex] = k;
}
e = e->next;
}
}
return uniun_Eq(P, 1, GL.numVertexes);
}
//并查集 判断1与K是否构成回路
int find_Eq(Patharc P, int i)
{
// printf("%d\n", P[i]);
while(P[i] > -1)
{
i = P[i];
}
return i;
}
int uniun_Eq(Patharc P, int start, int end)
{
int fi;
int fj;
fi = find_Eq(P, start);
fj = find_Eq(P, end);
if (fi != fj) //表明是两颗子树
{
return FALSE;
}
return TRUE; //可构成回路
}
int main()
{
int N, K;
int i;
graphAdjList GL;
Patharc P;
int p[MAXVEX];
int num;
int flag;
while (~scanf("%d%d", &N, &K))
{
if (N == 0 && K == 1) // 特殊没有路径 只有1个顶点
{
printf("0\n1\n");
continue;
}
CreateALGraph(&GL, N, K);
flag = ShortestPath_Dijkstra(GL, 1, P); //构成回路 TRUE,否则 FLASE
num = 0;
i = K;
if (flag == TRUE) //判断 如果构成回路 即有一条通往终点的路径
{
do
{
p[num++] = P[i];
i = P[i];
}
while (P[i] != -1);
printf("%d\n", num+1);
for (num--; num >= 0; num--)
{
printf("%d\n", p[num]); //输出路径
}
printf("%d\n", K);
}
else
{
printf("-1\n");
}
}
return 0;
}