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)的主要内容,如果未能解决你的问题,请参考以下文章