1 条题解

  • 1
    @ 2023-1-17 17:28:30

    建议使用 stringstream 读取数据。

    每条线路都说明线路中按顺序的任意两点可以一趟到达,依此建图即可。

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN = 100'000;
    const int MAXM = 200'000;
    int n, m, s; // 点数、边数、出发点编号
    struct Edge
    {
        int v, w;
    };
    vector<Edge> e[MAXN + 5];
    int dis[MAXN + 5];  // dis[i]: s->i 的最短路
    bool vis[MAXN + 5]; // vis[i]: i 号点是否已经确定了
    
    struct Point
    {
        int id, dis;
    };
    bool operator<(const Point &x, const Point &y)
    {
        return x.dis > y.dis;
    }
    priority_queue<Point> q;
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        // 输入
        cin >> m >> n;
        stringstream ss;
        string s;
        getline(cin, s); // 吃一个n后面的换行
        for (int t = 1; t <= m; t++)
        {
            getline(cin, s);
            ss.clear();
            ss << s;
            int last = -1, now;
            vector<int> points;
            while (ss >> now)
                points.push_back(now);
            for (int i = 0; i < points.size(); i++)
            {
                for (int j = i + 1; j < points.size(); j++)
                {
                    e[points[i]].push_back((Edge){points[j], 1});
                    //cout << points[i] << " " << points[j] << " " << 1 << "\n";
                }
            }
        }
        // dijkstra
        memset(dis, 0x3f, sizeof(dis));
        memset(vis, false, sizeof(vis));
        dis[1] = 0;
        q.push((Point){1, 0});
        for (int t = 1; t <= n - 1; t++)
        {
            // 找到当前距离最近且未确定的点
            while (!q.empty() && vis[q.top().id])
                q.pop();
            if (q.empty())
                break;
            int u = q.top().id;
            // u可以确定距离为 dis[u] 了
            vis[u] = true;
            // 用 u 优化其他点
            for (int i = 0; i < e[u].size(); i++)
            {
                int v = e[u][i].v;
                int w = e[u][i].w;
                if (vis[v])
                    continue;
                if (dis[u] + w < dis[v])
                {
                    dis[v] = dis[u] + w;
                    q.push((Point){v, dis[v]});
                }
            }
        }
    
        // 输出
        if (dis[n] == 0x3f3f3f3f)
            cout << "NO\n";
        else
            cout << dis[n] - 1 << "\n";
        return 0;
    }
    
    
    • 1

    信息

    ID
    606
    时间
    1000ms
    内存
    128MiB
    难度
    5
    标签
    (无)
    递交数
    33
    已通过
    14
    上传者