Tram

Tram

    题目大意:给你一个图,这个图上有n点和边。点上有开关,开关开始指向一条道路,拨动开关可以使开关指向由开关出发的任意一条路径,读入,a,b,求,至少要拨动几次才能从a点走到b点。 

    注释:n<=100.

      想法:最短路的题,由于n的范围,想采用floyd来处理。首先,说一下读入的方式:第一行3个整数n,a,b,接下来的n行,第i+1行的第一个数表示第i个点出发的有几条边,数据保证每条边会在两个点的读入中出现,而开关默认指向的方向就是所读进来的第二个数,也就是读进来的第一条边。这道题的正解就是强行为边附上边权。如果以这个点出发且开关直接指向这条边就把这条边的边权设为0,如果开关并不指向这条边,但这条边是一条轨道,我们就将这条边的边权设为1。这样,用floyd跑最短路,最后输出map[a][b]即可。

    最后,附上丑陋的代码... ...

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 int map[101][101];//所记录的边权,以及两点之间的最短路
 6 int main()
 7 {
 8     int n,a,b;
 9     int m,x;
10     while(~scanf("%d%d%d",&n,&a,&b))
11     {
12         memset(map,0x3f,sizeof(map));//每组数据开始前都必须将map数组清零
13         for(int i=1;i<=n;i++) map[i][i]=0;//特判掉a==b的情况
14         for(int i=1;i<=n;i++)//读入所有的轨道
15         {
16             scanf("%d",&m);
17             for(int j=1;j<=m;j++)
18             {
19                 scanf("%d",&x);
20                 if(j==1) map[i][x]=0;
21                 else map[i][x]=1;
22             }
23         }
24         for(int k=1;k<=n;++k)//floyd
25         {
26             for(int i=1;i<=n;++i)
27             {
28                 for(int j=1;j<=n;j++)
29                 {
30                     map[i][j]=min(map[i][j],map[i][k]+map[k][j]);
31                 }
32             }
33         }
34         if(map[a][b]==0x3f3f3f3f) printf("-1\n");//如果不行则输出-1
35         else printf("%d\n",map[a][b]);
36     }
37     return 0;
38 }

    小结,错误:无。

posted @ 2018-01-10 16:48  JZYshuraK_彧  阅读(356)  评论(0编辑  收藏  举报