Tram
Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 10231 | Accepted: 3739 |
Description
Tram network in Zagreb consists of a number of intersections and rails connecting some of them. In every intersection there is a switch pointing to the one of the rails going out of the intersection. When the tram enters the intersection it can leave only in the direction the switch is pointing. If the driver wants to go some other way, he/she has to manually change the switch.
When a driver has do drive from intersection A to the intersection B he/she tries to choose the route that will minimize the number of times he/she will have to change the switches manually.
Write a program that will calculate the minimal number of switch changes necessary to travel from intersection A to intersection B.
When a driver has do drive from intersection A to the intersection B he/she tries to choose the route that will minimize the number of times he/she will have to change the switches manually.
Write a program that will calculate the minimal number of switch changes necessary to travel from intersection A to intersection B.
Input
The first line of the input contains integers N, A and B, separated by a single blank character, 2 <= N <= 100, 1 <= A, B <= N, N is the number of intersections in the network, and intersections are numbered from 1 to N.
Each of the following N lines contain a sequence of integers separated by a single blank character. First number in the i-th line, Ki (0 <= Ki <= N-1), represents the number of rails going out of the i-th intersection. Next Ki numbers represents the intersections directly connected to the i-th intersection.Switch in the i-th intersection is initially pointing in the direction of the first intersection listed.
Each of the following N lines contain a sequence of integers separated by a single blank character. First number in the i-th line, Ki (0 <= Ki <= N-1), represents the number of rails going out of the i-th intersection. Next Ki numbers represents the intersections directly connected to the i-th intersection.Switch in the i-th intersection is initially pointing in the direction of the first intersection listed.
Output
The first and only line of the output should contain the target minimal number. If there is no route from A to B the line should contain the integer "-1".
Sample Input
3 2 1 2 2 3 2 3 1 2 1 2
Sample Output
0
Source
题意:
地区之间的铁路交织形成铁路网。有轨电车在每个路口都能根据该路口铁路的转向,去到不同的路口。虽然每个路口都有多条分岔路,但是每个路口只会指向其中的一条。若想要去其他的分岔路,则需要通过路口上的相应开关重新设置其转向。先给定各路口每条分岔路可到达的下一个路口,以及该路口一开始指向哪个路口。问若需要从某一路口到达另一路口,至少需要设置几次开关才能去到。
输入输出:
先给出N个点和A、B(起终点),接下来的N行分别为点i(1-N)的情况,第一个数表示与该点连通的个数,接下来给该行Ki个点,k1点所连为默认,通过不需要改转向,其余需要改一次转向,求改转向次数最少。
思路: 先构造有向图,将不需要改转向的路线设为0,否则为1,求最短路径即可。
/******************************
*
* acm: poj-1847
*
* title: Tram
*
* time :2014.8.26
*
*******************************/
/*
输入输出:
先给出N个点和A、B(起终点),接下来的N行分别为点i(1-N)的情况,
第一个数表示与该点连通的个数,接下来给该行Ki个点,k1点所连为默认,
通过不需要改转向,其余需要改一次转向,求改转向次数最少。
思路:
先构造有向图,将不需要改转向的路线设为0,否则为1,求最短路径即可。
*/
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define INFINITY 65535
#define MAXVEX 101
typedef int EdgeType;
//构造邻接矩阵
typedef struct MGraph
{
EdgeType arc[MAXVEX][MAXVEX];
int numVertexes;
} MGraph;
//初始化图结构
void CreateMGraph(MGraph *G)
{
int i, j;
int n; //点i的情况
int a;
for (i = 1; i <= G->numVertexes; i++)
{
for (j = i; j <= G->numVertexes; j++)
{
if (i == j)
{
G->arc[i][j] = 0;
}
else
{
G->arc[j][i] = G->arc[i][j] = INFINITY;
}
}
}
for (i = 1; i<= G->numVertexes; i++)
{
scanf("%d", &n); //点i的可能情况
for (j = 0; j < n; j++)
{
scanf("%d", &a);
if (j == 0)
{
G->arc[i][a] = 0;
}
else
{
G->arc[i][a] = 1;
}
}
}
/* 静态数据
G->arc[1][2] = 0;
G->arc[1][3] = 1;
G->arc[2][3] = 0;
G->arc[2][1] = 1;
G->arc[3][1] = 0;
G->arc[3][2] = 1;
*/
}
typedef int ShortPathTable[MAXVEX];
//Dijkstra 算法 D[v] 带权路径长度
int ShortestPath_Dijkstra(MGraph G, int v0, int vw)
{
int v, w, k, min;
int final[MAXVEX]; //final[w]=1 表示求得顶点v0至vw的最短路径
ShortPathTable D;
for (v = 1; v <= G.numVertexes; v++)
{
final[v] = 0; //全部顶点初始化为未知最短路径的状态
D[v] = G.arc[v0][v]; //将与v0有连线的顶点加上权值
}
final[v0] = 1;
//开始主循环,每次求得v0到某个v顶点的最短路径
for (v = 1; v < G.numVertexes; v++)
{
min = INFINITY;
for (w = 1; w <= G.numVertexes; w++) //寻找离v0最近的顶点
{
if (!final[w] && D[w] < min)
{
k = w;
min = D[w]; //w顶点离v0更近
}
}
final[k] = 1;
for (w = 1 ; w <= G.numVertexes; w++) //修正当前最短距离
{
//如果经过v顶点的路径比现在这条路径的长度短的话
if (!final[w] && (min + G.arc[k][w] < D[w]))
{
//说明找到了更短的路径,修改D[w]
D[w] = min + G.arc[k][w];
}
}
if (final[vw] == 1)
{
break;
}
}
if (D[vw] == INFINITY)
{
D[vw] = -1;
}
return D[vw];
}
int main()
{
int n;
int a;
int b;
MGraph G;
while (~scanf("%d", &G.numVertexes))
{
scanf("%d%d", &a, &b);
CreateMGraph(&G);
n = ShortestPath_Dijkstra(G, a, b);
printf("%d\n", n);
}
return 0;
}