最短路 || POJ 1847 Tram

本文介绍了解决POJ1847问题的方法,该问题要求求解从起点到终点最少需要改变多少次节点指向才能到达。通过使用SPFA算法并设置特殊边权值来实现这一目标。
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 = 0;
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 = 0; i < SZ; i++) dist[i] = INF, use[i] = 0;
    while(!q.empty()) q.pop();
    use[s] = 1;
    dist[s] = 0;
    q.push(s);
    while(!q.empty())
    {
        int u = q.front(); q.pop();
        use[u] = 0;
        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] = 1, q.push(v);
            }
        }
    }
    return dist[e];
}
int main()
{
    int n, a, b;
    scanf("%d %d %d", &n, &a, &b);
    for(int i = 1; i <= n; i++)
    {
        int k, x;
        scanf("%d", &k);
        if(k == 0) continue;//考虑k==0的情况
        scanf("%d", &x);
        build(i, x, 0);
        for(int j = 1; j < k; j++)
        {
            scanf("%d", &x);
            build(i, x, 1);
        }
    }
    int dis = spfa(a, b);
    if(dis == INF) printf("-1\n");
    else printf("%d\n", dis);
    return 0;
}

 

 

转载于:https://www.cnblogs.com/pinkglightning/p/8404713.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值