题意:
火车从1开到N 每个路口可以改变轨道事火车驶向不同的交叉路口 求改变路口(搬动开关)的最小次数
思路:
- 将路口为顶点
- 建边方式 1.原指向的路口权为0 2.后指向路口权唯一
- 使扳动次数尽可能少 故要么不扳要么只搬动一次。因此转化为最短路模型
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
#define MAX_V 105
#define INF 1<<30
struct edge{
int v;
int cost;
};
vector<edge> G[MAX_V];
int V;
bool inqueue[MAX_V];
int d[MAX_V];
void spfa(int s){
for (int i = 0;i<=V;i++)
d[i] = INF;
d[s] = 0; inqueue[s] = true;
memset(inqueue,0,sizeof inqueue);
queue<int> Q;
Q.push(s);
while (!Q.empty()){
int u = Q.front(); Q.pop(); inqueue[u] = false;
for (int i = 0;i<G[u].size();i++){
int v = G[u][i].v;
if (d[u] + G[u][i].cost < d[v]){
d[v] = d[u] + G[u][i].cost;
if (!inqueue[v]){
Q.push(v);
inqueue[v] = true;
}
}
}
}
}
int start,ending;
void init(){
scanf("%d%d%d",&V,&start,&ending);
for(int i = 1;i<=V;i++){
G[i].clear();
}
for (int i = 1;i<=V;i++){
int num,to;
scanf("%d%d",&num,&to);
G[i].push_back({to,0});
for (int j = 1;j<num;j++){
scanf("%d",&to);
G[i].push_back({to,1});
}
}
}
int main()
{
init();
spfa(start);
if (d[ending] != INF)
printf("%d\n",d[ending]);
else
printf("-1\n");
return 0;
}