CSP-J 2019 T4 加工零件 题解

CSP-J 2019 T4 加工零件 题解

前言

洛谷P5663 T4 加工零件(BFS,最短路)

题意

工厂里有 \(n\) 位工人,工人们从 \(1 \sim n\) 编号。某些工人之间存在双向的零件传送带。保证每两名工人之间最多只存在一条传送带。

如果 \(x\) 号工人想生产一个被加工到第 \(L\,(L \gt 1)\) 阶段的零件,则所有\(x\) 号工人有传送带直接相连的工人,都需要生产一个被加工到第 \(L - 1\) 阶段的零件(但 \(x\) 号工人自己无需生产第 \(L - 1\) 阶段的零件)。

如果 \(x\) 号工人想生产一个被加工到第 \(1\) 阶段的零件,则所有\(x\) 号工人有传送带直接相连的工人,都需要为 \(x\) 号工人提供一个原材料。

轩轩是 \(1\) 号工人。现在给出 \(q\) 张工单,第 \(i\) 张工单表示编号为 \(a_i\) 的工人想生产一个第 \(L_i\) 阶段的零件。轩轩想知道对于每张工单,他是否需要给别人提供原材料。

数据规模与约定

对于 \(100\%\) 的数据,保证 \(1 \le n,m,q \le 10^5,1 \le L \le 10^9\)

题解

显而易见题目给的是无向图

如果有一条 \(x \to y\) 的路径,长度为 \(dis\),那么一定存在长度为 \(dis + 2k(k \ne 0)\) 的路径(因为你可以在两个节点之间反复横跳)。

由于 \(dis\)\(dis + 2k\) 的奇偶性相同,所以我们要求出从节点 \(1\) 到节点 \(a\) 的奇数长度最短路径和偶数长度最短路径,这个可以用 BFS,也可以 Dijkstra、SPFA……不过 BFS 最简单,所以我们写 BFS。

求出最短路径后,如果最短路径 \(\le L\),那么输出 Yes,否则输出 No

特别注意:如果节点 \(a\) 和节点 \(1\) 不在一个连通块,那么肯定传播不到节点 \(1\)\(dis[a][L\&1]\) 就是 0x3F3F3F3F,记得特判。

Code

#include<bits/stdc++.h>
using namespace std;
/*====================*/
using lnt = long long;
/*====================*/
#define endl "\n"
/*====================*/
int n, m, q;
/*====================*/
const int N = 1e5 + 10;
/*====================*/
vector<int>adj[ N ];
/*====================*/
int dis[ N ][ 2 ]; 
//定义 dis(x, 0) 表示 x 节点到达 1 节点的最短「偶数长度」距离
//定义 dis(x, 1) 表示 x 节点到达 1 节点的最短「奇数长度」距离
/*====================*/
void BFS()
{
    queue<int>que;
    que.push(1);
    dis[ 1 ][ 0 ] = 0;

    while (!que.empty())
    {
        int u = que.front(); que.pop();

        for (auto v : adj[ u ])
        {
            bool need = false;

            if (dis[ v ][ 1 ] > dis[ u ][ 0 ] + 1)
            {
                dis[ v ][ 1 ] = dis[ u ][ 0 ] + 1;
                need = true;
            }
            if (dis[ v ][ 0 ] > dis[ u ][ 1 ] + 1)
            {
                dis[ v ][ 0 ] = dis[ u ][ 1 ] + 1;
                need = true;
            }

            if (need) que.push(v); //更新后才需要入队
            
        }
    }
}
/*====================*/
void Solve()
{
    memset(dis, 0x3F, sizeof(dis));

    cin >> n >> m >> q;
    for (int i = 1; i <= m; i++)
    {
        int u, v; cin >> u >> v;
        adj[ u ].push_back(v);
        adj[ v ].push_back(u);
    }

    BFS();

    for (int i = 1; i <= q; i++)
    {
        int num, lvl;
        cin >> num >> lvl;

        int dist = dis[ num ][ lvl & 1 ];

        if (dist == 0x3F3F3F3F)
        {
            cout << "No" << endl;
            continue;
        }

        if (dist <= lvl) cout << "Yes" << endl;
        else cout << "No" << endl;
    }
}
/*====================*/
int main()
{
    freopen("work.in", "r", stdin);
    freopen("work.out", "w", stdout);
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    int T = 1; //cin >> T;
    while (T--) Solve();
    return 0;
}
posted @ 2026-01-31 11:26  yufh  阅读(0)  评论(0)    收藏  举报
浏览器标题切换
浏览器标题切换end