CSP201912-4 區塊鏈(90分)
阿新 • • 發佈:2021-09-04
不知道為啥是90分,而且是錯誤不是超時...正在忙著寫web,等有時間再改吧
大體思路就是用佇列去模擬(一開始寫了個優先佇列亂排序喜提70,改成普通佇列就90了),node儲存時間和節點以及當前節點的區塊鏈。為什麼要存當前節點的區塊鏈?看看第二個樣例的前兩個詢問就明白了,如果不這麼存的話,2號節點就會收到1號節點區塊增加兩次的影響,查詢結果就會變成3 0 1 2了。因為鏈更新的原則,每次spread都不會擴展出太多的節點(複雜度不會證明),所以暴力copy vector也能得到大部分分。
#include <bits/stdc++.h> #define pb push_back #define N 200005 #define M 400005 #define pii pair<int,int> using namespace std; int n, m, t, k; int head[N], ver[2 * M], Next[2 * M], tot = 0; void add(int x, int y) { ver[++tot] = y, Next[tot] = head[x], head[x] = tot; } vector<int> b[N]; int tran(string s) { int ans = 0; for(int i = 0; i < s.size(); i++) { ans *= 10; ans += (s[i] - '0'); } return ans; } struct node { int t, x; vector<int> v; bool operator <(const node& o) const { // if(t != o.t) return t < o.t; // else if(b[x].size() != b[o.x].size()) return b[x].size() > b[o.x].size(); // else return b[x][b[x].size() - 1] < b[o.x][b[o.x].size() - 1]; return t < o.t; } }; //priority_queue<node> q; queue<node> q; //圖可能不連通 int main() { scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) b[i].pb(0); for(int i = 1; i <= m; i++) { int u, v; scanf("%d%d", &u, &v); add(u, v); add(v, u); } scanf("%d%d", &t, &k); getchar(); for(int i = 1; i <= k; i++) { char ss[100]; vector<int> v; cin.getline(ss, 100); string s(ss); s = s + " "; int lst = 0; for(int j = 0; j < s.size(); j++) { if(s[j] == ' ') { v.pb(tran(s.substr(lst, j - lst))); lst = j + 1; } } if(v.size() == 3) { int aa = v[0], bb = v[1], cc = v[2]; while(q.size()) { //node now = q.top(); node now = q.front(); q.pop(); if(-now.t + t > bb) { q.push(now); break; } else { for(int i = head[now.x]; i; i = Next[i]) { int y = ver[i]; node nxt; nxt.x = y; nxt.t = now.t - t; bool update = 0; if(b[now.x].size() > b[y].size()) { update = 1; b[y] = now.v; nxt.v = now.v; } else if(b[now.x].size() == b[y].size() && b[now.x][b[now.x].size() - 1] < b[y][b[y].size() - 1]) { update = 1; b[y] = now.v; nxt.v = now.v; } if(update) q.push(nxt); } } } node nxt; b[aa].pb(cc); nxt.x = aa; nxt.t = -bb; nxt.v = b[aa]; q.push(nxt); } else { int aa = v[0], bb = v[1]; while(q.size()) { //node now = q.top(); node now = q.front(); q.pop(); if(-now.t + t > bb) { q.push(now); break; } else { for(int i = head[now.x]; i; i = Next[i]) { int y = ver[i]; node nxt; nxt.x = y; nxt.t = now.t - t; bool update = 0; if(b[now.x].size() > b[y].size()) { update = 1; b[y] = now.v; nxt.v = now.v; } else if(b[now.x].size() == b[y].size() && b[now.x][b[now.x].size() - 1] < b[y][b[y].size() - 1]) { update = 1; b[y] = now.v; nxt.v = now.v; } if(update) q.push(nxt); } } } printf("%d ", (int)b[aa].size()); for(int i = 0; i < (int)b[aa].size(); i++) { printf("%d ", b[aa][i]); } puts(""); } } return 0; } //case 1 // 5 10 // 1 2 // 1 3 // 1 4 // 1 5 // 2 3 // 2 4 // 2 5 // 3 4 // 3 5 // 4 5 // 1 27 // 1 1 1 // 2 1 2 // 3 1 3 // 4 1 4 // 5 1 5 // 1 1 // 2 1 // 3 1 // 4 1 // 5 1 // 1 2 // 2 2 // 3 2 // 4 2 // 5 2 // 1 10 10 // 2 11 9 // 1 11 // 2 11 // 3 11 // 4 11 // 5 11 // 1 12 // 2 12 // 3 12 // 4 12 // 5 12 //case2 // 15 13 // 1 2 // 2 3 // 3 4 // 4 5 // 1 6 // 6 7 // 7 8 // 8 9 // 1 10 // 10 11 // 11 12 // 12 13 // 14 15 // 6 28 // 1 1 1 // 1 2 2 // 1 6 // 2 7 // 13 7 // 9 7 // 5 7 // 3 14 // 8 14 // 5 14 // 11 14 // 9 25 // 5 25 // 13 25 // 9 29 3 // 5 29 4 // 13 29 5 // 1 53 // 2 59 6 // 2 59 // 1 1000 // 3 1000 // 8 1000 // 9 1000 // 10 1000 // 13 1000 // 14 1000 // 15 1000