fjutacm 3700 这是一道数论题 : dijkstra O(mlogn) 二进制分类 O(k) 总复杂度 O(k * m * logn)

Posted darkscocu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 template <typename T>
 15 class Graphics {
 16 private:
 17     struct Edge {
 18         int to, next;
 19         T w;
 20     } edge[MAXM];
 21     int first[MAXN], sign;
 22     int sumOfPoint;
 23     struct Node{
 24         int to;
 25         T w;
 26         Node(int a, int b):to(a), w(b){}
 27         Node(){}
 28         bool friend operator < (const Node &a, const Node &b){
 29             return a.w > b.w;
 30         }
 31     };
 32 public:
 33     void clear(int n) {
 34         sumOfPoint = n;
 35         for(int i = 1; i <= n; i ++) {
 36             first[i] = -1;
 37         }
 38         sign = 0;
 39     }
 40     void addEdgeOneWay(int u, int v, int w) {
 41         edge[sign].to = v;
 42         edge[sign].w = w;
 43         edge[sign].next = first[u];
 44         first[u] = sign ++;
 45     }
 46     void addEdgeTwoWay(int u, int v, int w) {
 47         addEdgeOneWay(u, v, w);
 48         addEdgeOneWay(v, u, w);
 49     }
 50     vector<T> dijkstra(const vector<int> &start) {
 51         vector<T> dist(sumOfPoint+1, INF);
 52         vector<bool> visit(sumOfPoint+1);
 53         priority_queue<Node> bfs;
 54         for(unsigned i = 0; i < start.size(); i ++) {
 55             bfs.push(Node(start[i], 0));
 56         }
 57         while(!bfs.empty()) {
 58             Node now = bfs.top();
 59             bfs.pop();
 60             if(visit[now.to]) {
 61                 continue;
 62             }
 63             visit[now.to] = true;
 64             dist[now.to] = now.w;
 65             for(int i = first[now.to]; i != -1; i = edge[i].next) {
 66                 int to = edge[i].to, w = edge[i].w;
 67                 if(!visit[to]) {
 68                     bfs.push(Node(to, now.w + w));
 69                 }
 70             }
 71         }
 72         return dist;
 73     }
 74 };
 75 
 76 class Solution {
 77 private:
 78     int n, m, u, v, w, k;
 79     int kk[MAXN];
 80     Graphics<int> graph;
 81 public:
 82     void solve() {
 83         int t;
 84         scanf("%d", &t);
 85         while(t --) {
 86             scanf("%d%d", &n, &m);
 87             graph.clear(n);
 88             while(m --) {
 89                 scanf("%d%d%d", &u, &v, &w);
 90                 graph.addEdgeOneWay(u, v, w);
 91             }
 92             scanf("%d", &k);
 93             for(int i = 0; i < k; i ++) {
 94                 scanf("%d", &kk[i]);
 95             }
 96             int ans = INF;
 97             for(int i = 0; i < 10; i ++) {
 98                 vector<int> first, second;
 99                 for(int j = 0; j < k; j ++) {
100                     if(kk[j] >> i & 1) {
101                         first.push_back(kk[j]);
102                     } else {
103                         second.push_back(kk[j]);
104                     }
105                 }
106                 vector<int> cur = graph.dijkstra(first);
107                 for(unsigned j = 0; j < second.size(); j ++) {
108                     ans = min(ans, cur[second[j]]);
109                 }
110                 cur = graph.dijkstra(second);
111                 for(unsigned j = 0; j < first.size(); j ++){
112                     ans = min(ans, cur[first[j]]);
113                 }
114             }
115             printf("%d\n", ans);
116         }
117     }
118 } DarkScoCu;
119 
120 int main() {
121     DarkScoCu.solve();
122     return 0;
123 }

 

以上是关于fjutacm 3700 这是一道数论题 : dijkstra O(mlogn) 二进制分类 O(k) 总复杂度 O(k * m * logn)的主要内容,如果未能解决你的问题,请参考以下文章

FJUT3703 这还是一道数论题(二分 + hash + manacher)题解

BZOJ 3209 花神的数论题

题解Luogu P4317 花神的数论题 组合数

郑州大学2018新生训练赛第十场题解

有趣的两道数论题——2017华杯初赛小高组

ra (数论 , 莫比乌斯反演 , 整点统计)