zoukankan      html  css  js  c++  java
  • fjutacm 3700 这是一道数论题 : dijkstra O(mlogn) 二进制分类 O(k) 总复杂度 O(k * m * logn)

      1 /**
      2 problem: http://www.fjutacm.com/Problem.jsp?pid=3700
      3 按二进制将k个待查点分类分别跑dijkstra
      4 **/
      5 #include<stdio.h>
      6 #include<vector>
      7 #include<queue>
      8 using namespace std;
      9 
     10 const int MAXN = 505;
     11 const int MAXM = 3e4+5;
     12 const int INF = 0x3f3f3f3f;
     13 
     14 int ans;
     15 
     16 template <typename T>
     17 class Graphics {
     18 private:
     19     struct Edge {
     20         int to, next;
     21         T w;
     22     } edge[MAXM];
     23     int first[MAXN], sign;
     24     int sumOfPoint;
     25     struct Node{
     26         int to;
     27         T w;
     28         Node(int a, int b):to(a), w(b){}
     29         Node(){}
     30         bool friend operator < (const Node &a, const Node &b){
     31             return a.w > b.w;
     32         }
     33     };
     34 public:
     35     void clear(int n) {
     36         sumOfPoint = n;
     37         for(int i = 1; i <= n; i ++) {
     38             first[i] = -1;
     39         }
     40         sign = 0;
     41     }
     42     void addEdgeOneWay(int u, int v, int w) {
     43         edge[sign].to = v;
     44         edge[sign].w = w;
     45         edge[sign].next = first[u];
     46         first[u] = sign ++;
     47     }
     48     void addEdgeTwoWay(int u, int v, int w) {
     49         addEdgeOneWay(u, v, w);
     50         addEdgeOneWay(v, u, w);
     51     }
     52     vector<T> dijkstra(const vector<int> &start) {
     53         vector<T> dist(sumOfPoint+1, INF);
     54         vector<bool> visit(sumOfPoint+1);
     55         priority_queue<Node> bfs;
     56         for(unsigned i = 0; i < start.size(); i ++) {
     57             bfs.push(Node(start[i], 0));
     58         }
     59         while(!bfs.empty()) {
     60             Node now = bfs.top();
     61             bfs.pop();
     62             if(visit[now.to]) {
     63                 continue;
     64             }
     65             visit[now.to] = true;
     66             dist[now.to] = now.w;
     67             for(int i = first[now.to]; i != -1; i = edge[i].next) {
     68                 int to = edge[i].to, w = edge[i].w;
     69                 if(now.w + w > ans) continue; /// 剪枝 当最短路已经大于当前最优值也不用继续找了
     70                 if(!visit[to]) {
     71                     bfs.push(Node(to, now.w + w));
     72                 }
     73             }
     74         }
     75         return dist;
     76     }
     77 };
     78 
     79 class Solution {
     80 private:
     81     int n, m, u, v, w, k;
     82     int kk[MAXN];
     83     Graphics<int> graph;
     84 public:
     85     void solve() {
     86         int t;
     87         scanf("%d", &t);
     88         while(t --) {
     89             scanf("%d%d", &n, &m);
     90             graph.clear(n);
     91             while(m --) {
     92                 scanf("%d%d%d", &u, &v, &w);
     93                 graph.addEdgeOneWay(u, v, w);
     94             }
     95             scanf("%d", &k);
     96             for(int i = 0; i < k; i ++) {
     97                 scanf("%d", &kk[i]);
     98             }
     99             ans = INF;
    100             for(int i = 0; i < 10; i ++) {
    101                 vector<int> first, second;
    102                 for(int j = 0; j < k; j ++) {
    103                     if(kk[j] >> i & 1) {
    104                         first.push_back(kk[j]);
    105                     } else {
    106                         second.push_back(kk[j]);
    107                     }
    108                 }
    109                 vector<int> cur = graph.dijkstra(first);
    110                 for(unsigned j = 0; j < second.size(); j ++) {
    111                     ans = min(ans, cur[second[j]]);
    112                 }
    113                 cur = graph.dijkstra(second);
    114                 for(unsigned j = 0; j < first.size(); j ++){
    115                     ans = min(ans, cur[first[j]]);
    116                 }
    117             }
    118             printf("%d
    ", ans);
    119         }
    120     }
    121 } DarkScoCu;
    122 
    123 int main() {
    124     DarkScoCu.solve();
    125     return 0;
    126 }
  • 相关阅读:
    awk书上练习
    矩阵运算
    从最大似然到EM算法浅解
    numpy 练习
    python lxml教程
    pycharm快捷键
    python正则表达式教程
    三门问题
    Solr本地服务器搭建及查询
    git简单使用
  • 原文地址:https://www.cnblogs.com/DarkScoCu/p/10699178.html
Copyright © 2011-2022 走看看