zoukankan      html  css  js  c++  java
  • CSU 2005: Nearest Maintenance Point(Dijkstra + bitset)

    Description

    A county consists of n cities (labeled 1, 2, …, n) connected by some bidirectional roads. Each road connects a pair of distinct cities. A robot company has built maintenance points in some cities. Now, they need your help to write a program to query the nearest maintenance point to a specific city.

    Input

    There will be at most 200 test cases. Each case begins with four integers n, m, s, q(2 ≤ n ≤ 104, 1 ≤ m ≤ 5 × 104, 1 ≤ s ≤ min{n, 1000},1 ≤ q ≤ min{n, 1000}), the number of cities, the number of roads, the number of cities which have maintenance points and the number of queries. Then m lines contain the descriptions of roads. Each of them contains three integers ui, vi, wi(1 ≤ ui, vi ≤ n, ui ≠ vi, 1 ≤ wi ≤ 1000), denoting there is a road of length wi which connects city ui and vi. The next line contains s integers, denoting the cities which have maintenance points. Then q lines contain the descriptions of queries. Each of them contains one integer denoting a specific city. The size of the whole input file does not exceed 6MB.

    Output

    For each query, print the nearest city which has a maintenance point. If there are multiple such cities, print all of them in increasing order separated by a single space. It is guaranteed that there will be at least one such city.

    Sample Input

    4 4 2 3
    1 2 1
    2 3 2
    2 4 1
    4 3 2
    1 3
    3
    2
    4

    Sample Output

    3
    1
    1 3

    题目大意:有n个城市,m条边将一些城市连接起来,现在有s个城市维护点,q次查询,现在对于每一次查询的城市,输出离他最近的城市维护点,如果有多个则按递增顺序打印。
    思路: 把s个城市维护点当起点搜一下最短路,其中用bitset来维护其他城市距离维护点最近的那个起点,对于城市x来说,若有多个起点城市到它的最短距离是相等的就用或运算将之存在bitset,否则直接将最短的那一个维护点赋值给x
      代码上也做了一些注释(如果对于bitset不是很熟悉的可以向大家推荐一篇感觉还不错的博客。http://www.cppblog.com/ylfeng/archive/2010/03/26/110592.html
     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<bitset>
     5 #include<vector>
     6 #include<queue>
     7 
     8 using namespace std;
     9 const int INF = 1 << 28;
    10 const int maxn = 20005;
    11 struct node {
    12     int to, cost;
    13     node() {}
    14     node(int a, int b) :to(a), cost(b) {}
    15     bool operator<(const node&a)const {
    16         return cost > a.cost;
    17     }
    18 };
    19 vector<node>e[maxn];
    20 bitset<1005>bt[maxn];
    21 int n, m, s, q;
    22 int dis[maxn], cha[maxn], vis[maxn];
    23 void Dijkstra()
    24 {
    25     priority_queue<node>Q;
    26     for (int i = 1; i <= n; i++) {
    27         dis[i] = INF; bt[i].reset();//初始化距离和清空bitset表
    28         vis[i] = 0;
    29     }
    30     for (int i = 1; i <= s; i++) {
    31         dis[cha[i]] = 0;
    32         Q.push(node(cha[i], dis[cha[i]]));
    33         bt[cha[i]][i] = 1;//bt[i][j] = 1 代表第i个城市最近的城市维护点是第j个
    34     }
    35     while (!Q.empty()) {
    36         node t = Q.top(); Q.pop();
    37         if (vis[t.to])continue;
    38         vis[t.to] = 1;//对于每一个点我们只需要以他为起点遍历一次就ok,避免大量的重复计算
    39         for (int i = 0; i < e[t.to].size(); i++) {
    40             int tmp = e[t.to][i].to;
    41             int ct = e[t.to][i].cost;
    42             if (dis[tmp] > dis[t.to] + ct) {
    43                 dis[tmp] = dis[t.to] + ct;
    44                 Q.push(node(tmp, dis[tmp]));
    45                 bt[tmp] = bt[t.to];//如果有比当前更近的城市维护点则将更近的维护点赋值给现在的点
    46             }
    47             else if (dis[tmp] == (dis[t.to] + ct))
    48                 bt[tmp] |= bt[t.to];//如果有多个城市维护点的距离相同就取或赋值
    49         }
    50     }
    51 }
    52 int main()
    53 {
    54     while (scanf("%d%d%d%d", &n, &m, &s, &q) != EOF) {
    55         for (int i = 1; i <= n; i++)e[i].clear();
    56         for (int a, b, c, i = 0; i < m; i++) {
    57             scanf("%d%d%d", &a, &b, &c);
    58             e[a].push_back(node(b, c));
    59             e[b].push_back(node(a, c));
    60         }
    61         for (int i = 1; i <= s; i++)scanf("%d", &cha[i]);
    62         sort(cha + 1, cha + s + 1);//因为题目要我们如果有多个点满足要求,则递增输出,所以我们可以事先排个序
    63         Dijkstra();
    64         int x;
    65         while (q--) {
    66             int a[1010], cnt = 0;
    67             scanf("%d", &x);
    68             for (int i = 1; i <= s; i++)
    69                 if (bt[x][i])//对于s个城市维护点来说,若bt[x][i]==1则代表第i个城市到x的距离是最近的
    70                     a[++cnt] = cha[i];
    71             for (int i = 1; i < cnt; i++)
    72                 printf("%d ", a[i]);//最后按格式输出即可
    73             printf("%d
    ", a[cnt]);
    74         }
    75     }
    76     return 0;
    77 }
  • 相关阅读:
    Python3字典中items()和python2.x中iteritems()有什么区别
    python中使用zip函数出现<zip object at 0x02A9E418>
    python中字符串连接的四种方式
    Python如何规定对方输入的数字必须是整数?
    C# 自定义控件VS用户控件
    c#使用Split分割换行符
    C# 读取app.config配置文件 节点键值,提示 "配置系统未能初始化" 错误的解决方案
    安装MySql for Visual Studio的坑
    MySql Access denied for user 'root'@'localhost' (using password:YES) 解决方案
    VS2010 VS2012 VS2013 VS2015启动调试时老是提示正在下载公共符号
  • 原文地址:https://www.cnblogs.com/wangrunhu/p/9506922.html
Copyright © 2011-2022 走看看