P5663 [CSP-J2019] 加工零件


前言

其实我感觉本题的难点在于分成奇偶两个不同的最短路来计算,图论和最短路其实不难想。


题目大意

题面有点长,还是放一下链接吧。题目传送门


思路

首先看到这题,图论肯定能想到。之后就可以想出一个暴力做法,模拟一遍这个过程,做一次dfs,然后判断。光看到 L L L 的范围就知道肯定不对。之后想了想,这个 L L L 的范围肯定没有什么在线处理 log ⁡ n \log{n} logn 的算法了,极大可能要做预处理然后 O ( 1 ) \mathcal{O}(1) O(1) 回答。

之后让我们转化一下思路,其实就是问在 a a a 1 1 1 之间存不存在一条长度为 L L L 的路径。考虑最短路,如果从 a a a 1 1 1 的最短路比 L L L 大,那么肯定 L L L 开始不需要到。但是可能出现来回来回的情况。

之后再次进行考虑,可以发现,在两条边之间来回走就可以自给自足了,每一次来回增加 1 1 1 的阶段需要走两次,也就是如果这条边的最短路走出来了 3 3 3,那么也一定可以走出 5 , 7 ⋯ 5,7\cdots 5,7但是不可以确定能否走出 6 6 6,但是偶数如果走出来 2 2 2 就一定可以走出 6 6 6,所以要按照奇偶分最短路。之后在根据 L L L 的奇偶对奇偶最短路进行判断即可。

需要注意,如果 1 1 1 是孤立的,则它没有偶数最短路,所以做bfs时先把 1 1 1 的连接边放进队列里即可。


代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
const ll MAXN=1e5+5;
vector<ll>adj[MAXN];
ll dis[MAXN][3];
ll n,m,Q;
int main(){
    scanf("%lld%lld%lld",&n,&m,&Q);
    for (int i = 1; i <=m ; ++i) {
        ll u,v;
        scanf("%lld%lld",&u,&v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    memset(dis,0x3f,sizeof(dis));
    queue<pair<ll,ll> >q;
    for (int i = 0; i <adj[1].size() ; ++i) {
        ll v=adj[1][i];
        dis[v][1]=1;
        q.push({v,1});
    }
    while (!q.empty()){
        ll u=q.front().first,w=q.front().second+1;
        q.pop();
        for (int i = 0; i <adj[u].size() ; ++i) {
            ll v=adj[u][i],type=w%2;
            if(w<dis[v][type]){
                dis[v][type]=w;
                q.push({v,w});
            }
        }
    }
    for (int T = 1; T <=Q ; ++T) {
        ll a,L;
        scanf("%lld%lld",&a,&L);
        if(dis[a][L%2]>L){
            printf("No\n");
        }else{
            printf("Yes\n");
        }
    }
    return 0;
}


总结

我们知道了本题可以使用奇偶最短路进行判断,同时可以根据暴力和输入数据的大小去推断可能的算法。在本题中我们通过暴力和 L L L 的范围推断出不太可能有在线的做法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值