zoukankan      html  css  js  c++  java
  • cf536d——优先队列的运用

    题目

    题目: Lunar New Year and a Wander

    题目大意:给定一个n个顶点(编号1~n)、m条边的图,求从顶点1出发的字典序最小的路径(途径的边可重复)。

    思路

    使用一个优先队列就足够了。当访问一个节点,我们将与之相连的、未被访问的节点加入队列,每次取优先队列的队首进行访问。即优先队列中存放的是当前所有可到达且未被访问的节点(因为路径可重复)。

    时间复杂度:$mathcal{O}(m log n)$

    代码

    priority_queue版

     1 #include<cstdio>
     2 #include<queue>
     3 #include<vector>
     4 using namespace std;
     5 
     6 typedef long long LL;
     7 const int maxn = 100000 + 10;
     8 vector<int>e[maxn];
     9 vector<int>seq;
    10 bool vis[maxn];
    11 int n, m;
    12 priority_queue<int, vector<int>, greater<int>>Q;
    13 
    14 int main()
    15 {
    16     scanf("%d%d", &n, &m);
    17     for (int i = 0; i < m; i++)
    18     {
    19         int u, v;
    20         scanf("%d%d", &u, &v);
    21         e[u].push_back(v);
    22         e[v].push_back(u);
    23     }
    24     vis[1] = true;
    25     Q.push(1);
    26     while (!Q.empty())
    27     {
    28         int now = Q.top(); Q.pop();
    29         seq.push_back(now);
    30         for (int i = 0; i < e[now].size(); i++)
    31         {
    32             if (!vis[e[now][i]])
    33             {
    34                 Q.push(e[now][i]);
    35                 vis[e[now][i]] = true;
    36             }
    37         }
    38     }
    39     for (int i = 0; i < seq.size(); i++)
    40         printf("%d%c", seq[i], i == seq.size() - 1 ? '
    ' : ' ');
    41     return 0;
    42 }

    set版(set也能排序,且这里节点值不重复)

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<set>
     4 #include<vector>
     5 #include<algorithm>
     6 using namespace std;
     7 
     8 typedef long long ll;
     9 const int maxn = 300000 + 10;
    10 int n, m;
    11 vector<int>vec[maxn];
    12 bool visited[maxn];
    13 
    14 int main()
    15 {
    16     scanf("%d%d", &n, &m);
    17     for (int i = 0;i < m; i++)
    18     {
    19         int u, v;
    20         scanf("%d%d", &u, &v);
    21         vec[u].push_back(v);
    22         vec[v].push_back(u);
    23     }
    24     vector<int>ans;
    25     set<int>st;
    26     st.insert(1);
    27     for (int i = 0; i < n; i++)
    28     {
    29         int u, v;
    30         u = *(st.begin());
    31         ans.push_back(u);
    32         visited[u] = true;
    33         st.erase(u);
    34         for (int j = 0; j < vec[u].size(); j++)
    35         {
    36             v = vec[u][j];
    37             if (!visited[v])  st.insert(v);
    38         }
    39     }
    40     int len = ans.size();
    41     for (int i = 0; i < len; i++)  printf("%d%c", ans[i], i == len - 1 ? '
    ' : ' ');
    42 
    43     return 0;
    44 }

    参考链接:https://codeforces.com/blog/entry/64928

  • 相关阅读:
    DIV 设置垂直居中
    JavaScript--什么是函数
    JavaScript--引用JS外部文件
    JavaScript--如何插入JS
    CSS-类和ID选择器的区别
    CSS-ID选择器
    CSS类选择器
    CSS样式介绍
    HTML--使用mailto在网页中链接Email地址
    HTML--form表单中的label标签
  • 原文地址:https://www.cnblogs.com/lfri/p/10346275.html
Copyright © 2011-2022 走看看