题意:题意难理解,
3 2 1
2 2 3
2 3 1
2 1 2
样例输入中,测试用例第一行包含3个数字N,A,B N代表结点个数,A代表起点,B代表终点,接下来有N行,每行第一个数是一个总数,如第1行第一个数为2,代表从结点1可以到达的结点数,接下来的第二个数2为默认的到达结点,剩下的都需要手动摇动开关才能走的方向。求从A到B最小的摇动次数,如果不能到达,输出-1
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 110;
const int INF = 1<<30;
int N,A,B;
int d[maxn],vis[maxn];
vector<int> g[maxn];
vector<int> w[maxn];
struct node
{
int d,x;//d值最小的编号
node(int d,int x):
d(d),x(x){
}
bool operator < (const node &b)const
{
return d>b.d;
}
};
int main()
{
priority_queue<node,vector<node> > q;
while(scanf("%d%d%d",&N,&A,&B)!=EOF)
{
for(int i=1;i<=N;i++)
{
g[i].clear();
w[i].clear();
}
for(int i=1;i<=N;i++)
{
int a,v;
scanf("%d",&a);
scanf("%d",&v);
g[i].push_back(v);
w[i].push_back(0);
for(int j=1;j<a;j++)
{
scanf("%d",&v);
g[i].push_back(v);
w[i].push_back(1);
}
}
for(int i=1;i<=N;i++)d[i]=INF;//除起点初始为0外,其余点均为无穷大
d[A]=0;
memset(vis,0,sizeof(vis));
while(!q.empty())q.pop();
q.push(node(0,A));
while(!q.empty())
{
node a=q.top();q.pop(); //选取d值最小的点
int x = a.x;
if(vis[x])continue; //访问一次
vis[x]=1;
for(int i=0;i<g[x].size();i++)
{
int y = g[x][i];
if(d[y]>d[x]+w[x][i])
{
d[y]=d[x]+w[x][i];
q.push(node(d[y],y));
}
}
}
if(d[B]!=INF)
printf("%d\n",d[B]);
else
printf("-1\n");
}
}