CSP201912-4 区块链(90分)

不知道为啥是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




原文地址:https://www.cnblogs.com/lipoicyclic/p/15226543.html