CSP历年复赛题-P5663 [CSP-J2019] 加工零件

原题链接:https://www.luogu.com.cn/problem/P5663

题意解读:工人是图中的点,传送带是图中的无向边,给出q个询问a, l,判断是否能有一条1号点到a点的路径为l。

解题思路:

考试的关键是拿分!同样可以来面向数据编程:

1、测试点 1∼41≤𝑛,𝑚≤1000𝐿=1

由于L=1,距离1号点路径为1,说明存在1号点到询问点之间的边,直接通过邻接矩阵即可判断

20分代码:

#include <bits/stdc++.h>
using namespace std;

const int N = 1005, M = 1005;
int n, m, q;
int g[N][N];

int main()
{
    cin >> n >> m >> q;
    int u, v;
    for(int i = 1; i <= m; i++)
    {
        cin >> u >> v;
        g[u][v] = g[v][u] = 1;
    }
    int a, l;
    while(q--)
    {
        cin >> a >> l;
        if(g[1][a] == 1) cout << "Yes" << endl;
        else cout << "No" << endl;
    }

    return 0;
}

2、测试点 5∼8,,

#include <bits/stdc++.h>
using namespace std;

const int N = 1005, M = 1005;
int n, m, q;
vector<int> g[N];
bool d[N][15]; //d[i][j]=true表示从1号点到i点有一条路径距离为j

void dfs(int u, int dist)
{
    if(dist > 10) return;
    if(d[u][dist]) return;
    d[u][dist] = true;
    for(int v : g[u])
    {
        dfs(v, dist + 1);
    }
}

int main()
{
    cin >> n >> m >> q;
    int u, v;
    for(int i = 1; i <= m; i++)
    {
        cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dfs(1, 0);
    int a, l;
    while(q--)
    {
        cin >> a >> l;
        if(d[a][l]) cout << "Yes" << endl;
        else cout << "No" << endl;
    }

    return 0;
}

3、其余数据

由于此题是求从1点到其他点可能的所有路径长度,普通的最短路如果通过bfs某个点不会重复走,但此题不一定是求最短路,可能是经过了一圈之后又回到某个点。

进一步分析,假设从1点到a的最短路径是l,那么必然可以存在从a点经过一个相邻点往返一次回到a点的路径l+2,

同理到a点的路径还有l+4,l+6,l+8,l+10....,也就是说与从1到a的最短路同奇偶性的路径都能到达

那么,就只需要计算从1到a的最短路,有两种:奇数的最短路、偶数的最短路,其余的都不需要计算

定一个数据变量保存每个点到1的距离:dist[N][2],dist[i][0]表示1到i点的偶数最短路,dist[i][1]表示1到i点的奇数最短路

通过bfs计算最短路,通过dist来更新距离同时用作已走过的标记

对于q个询问a,l,判断l的奇偶性,再看a的奇或者偶最短路是否小于等于l。

100分代码:

#include <bits/stdc++.h>
using namespace std;

const int N = 100005;
int n, m, q;
vector<int> g[N];
int dist[N][2]; 

struct node
{
    int id; //节点编号
    int distance; //距离1号点距离
};

void bfs()
{
    memset(dist, -1, sizeof(dist));
    queue<node> q;
    q.push({1, 0});
    dist[1][0] = 0;
    while(q.size())
    {
        node a = q.front();
        q.pop();
        for(int v : g[a.id])
        {
            if(dist[v][(a.distance + 1) % 2] == -1)
            {
                dist[v][(a.distance + 1) % 2] = a.distance + 1;
                q.push({v, a.distance + 1});
            }
        }
    }
}

int main()
{
    cin >> n >> m >> q;
    int u, v;
    for(int i = 1; i <= m; i++)
    {
        cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    bfs();
    int a, l;
    while(q--)
    {
        cin >> a >> l;
        if(dist[a][l % 2] != -1 && l >= dist[a][l % 2]) cout << "Yes" << endl;
        else cout << "No" << endl;
    }

    return 0;
}

 

posted @ 2024-06-13 10:13  五月江城  阅读(13)  评论(0编辑  收藏  举报