最短路 || POJ 1847 Tram

时间:2023-03-09 06:04:33
最短路 || POJ 1847 Tram
POJ 1847 最短路
每个点都有初始指向,问从起点到终点最少要改变多少次点的指向
*初始指向的那条边长度为0,其他的长度为1,表示要改变一次指向,然后最短路
=========高亮!!!==========数组要开n^2的QAQ
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
#define SZ 10005//开n^2的数组!!
#define INF 1e9+10
int head[SZ], nxt[SZ], tot = ;
struct edge
{
int t, d;
}l[SZ];
void build(int f, int t, int d)
{
l[++tot] = (edge){t, d};
nxt[tot] = head[f];
head[f] = tot;
}
int dist[SZ];
bool use[SZ];
queue<int> q;
int spfa(int s, int e)
{
for(int i = ; i < SZ; i++) dist[i] = INF, use[i] = ;
while(!q.empty()) q.pop();
use[s] = ;
dist[s] = ;
q.push(s);
while(!q.empty())
{
int u = q.front(); q.pop();
use[u] = ;
for(int i = head[u];i;i = nxt[i])
{
int v = l[i].t;
if(dist[v] > dist[u] + l[i].d)
{
dist[v] = dist[u] + l[i].d;
if(!use[v])
use[v] = , q.push(v);
}
}
}
return dist[e];
}
int main()
{
int n, a, b;
scanf("%d %d %d", &n, &a, &b);
for(int i = ; i <= n; i++)
{
int k, x;
scanf("%d", &k);
if(k == ) continue;//考虑k==0的情况
scanf("%d", &x);
build(i, x, );
for(int j = ; j < k; j++)
{
scanf("%d", &x);
build(i, x, );
}
}
int dis = spfa(a, b);
if(dis == INF) printf("-1\n");
else printf("%d\n", dis);
return ;
}