Tram POJ - 1847
思路:直接建图,机翻的题目看了好久才看懂,很简单的一个最短路,把能直接通过的边权赋为0,需要操作之后才能通过的边权赋为1
样例大意:
3 2 1
2 2 3
2 3 1
2 1 2
第一行分别是n、a、b
第二行意思是点1能到达两个站点2和3,到2不用转向,到3需要手动转向,下边一样
具体代码如下
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
const int N = 110, M = N*2;
int n, s, t;
int h[N], e[M], w[M], ne[M], idx;
int dis[N];
bool st[N];
void add(int a, int b, int c){
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}
void spfa(){
memset(dis, 0x3f, sizeof dis);
dis[s] = 0;
queue<int> q;
q.push(s);
while(q.size()){
int t = q.front();
q.pop();
st[t] = false;
for(int i=h[t]; ~i; i=ne[i]){
int j = e[i];
if(dis[j] > dis[t] + w[i]){
dis[j] = dis[t] + w[i];
if(!st[j]){
st[j] = true;
q.push(j);
}
}
}
}
}
int main(){
memset(h, -1, sizeof h);
scanf("%d%d%d", &n, &s, &t);
for(int i=1; i<=n; ++i){
int x;
scanf("%d", &x);
if(!x) continue;
int node;
x--;
scanf("%d", &node);
add(i, node, 0);
while(x--){
scanf("%d", &node);
add(i, node, 1);
}
}
spfa();
if(dis[t] == 0x3f3f3f3f) puts("-1");
else printf("%d\n", dis[t]);
return 0;
}