【bfs && 反向建边】2016-2017 ACM-ICPC, Egyptian Collegiate Programming Contest (ECPC 16) Jumping

Problem Description

输入T代表有T组测试数据,输入n代表有n个商城分别是1-n。每个商城都有一个值num,在这个商城可以直接跳到i-num的商城 or i+num的商城。问你每个商城到n这个商城最少需要跳几次,如果不能到输出-1。

思路:

看到这个题第一反应想到的是记忆化搜索,因为求的一个商城的最少跳跃距离,就可以用数组保存起来,下次在访问到直接返回值就可以了。也许是个人水平问题,样例过了,没能AC。百度看了下别人做法,求n到各个点的最短距离,不就是反向建边,跑bfs而已。

#include<bits/stdc++.h>
using namespace std;
struct node
{
    int to, next;
};
#define nn 112345
#define inf 0x3f3f3f3f
node Map[5*nn];
int head[nn], dist[nn], cnt;
void add(int u, int v)
{
    Map[cnt].to = v;
    Map[cnt].next = head[u];
    head[u] = cnt++;
}
void bfs(int u)
{
    memset(dist, inf, sizeof(dist));
    dist[u] = 0;
    queue<int> q;
    q.push(u);
    while(!q.empty())
    {
        u = q.front(), q.pop();
        for(int i = head[u]; ~i; i = Map[i].next)
        {
            int to = Map[i].to;
            if(dist[to] > dist[u] + 1)
            {
                dist[to] = dist[u] + 1;
                q.push(to);
            }
        }
    }
}
int main()
{
    freopen("jumping.in", "r", stdin);//因为这个写在了while()循环里面错了好久。。
    int T, n, num;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d", &n);
        memset(head, -1, sizeof(head));
        cnt = 0;
        for(int i = 1; i <= n; i++)
        {
            scanf("%d", &num);
            if(i-num >= 1) add(i-num, i);//反向建边
            if(i+num <= n) add(i+num, i);
        }
        bfs(n);//求n到各个点的最短路
        for(int i = 1; i <= n; i++)
        {
            if(dist[i] != inf) printf("%d\n", dist[i]);
            else printf("-1\n");
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值