201912-4 区块链

试题编号: 201912-4
试题名称: 区块链
时间限制: 10.0s
内存限制: 512.0MB
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述
思路from网上:按照时间顺序依次处理每个节点接收链和产生块。详见代码注释
小技巧:每个节点的接收链在传递的时候可以更新,因此接收链实际上可以是一条。

#include<iostream>
#include<map>
#include<unordered_map>
#include<array>
#include<vector>
using namespace std;
const int N=505;
map<int,unordered_map<int,array<vector<int>,2>>> act; //act[t][v][0]表示在t时刻,节点v的接收链; act[t][v][0]表示在t时刻,节点v的更新块链 
vector<int> graph[N]; //存储图 
vector<int> res[N]; //存储每个节点的主链 
int n,m,t; 

bool can_rec(vector<int>& rec,vector<int>& v) //判断rec能否更新主链v 
{
	return v.size()==rec.size()?v.back()>rec.back():v.size()<rec.size();
}

void spread(int v,int time)  //节点v向相邻节点传播主链 
{
	for(int rec_v:graph[v])
	{
		auto &chain=act[time][rec_v][0];
		if(can_rec(res[v],chain)) chain=res[v];
	}
}

void query(int v,int time)  //查询节点v在time时刻的主链,查询时才执行所有更新处理 
{
	for(auto &action:act)
	{
		int cur_t=action.first;
		if(cur_t>time) break;  //只处理到当前查询时刻 
		for(auto &temp:action.second)
		{
			int cur_v=temp.first;
			auto &rec=temp.second[0],&add=temp.second[1]; //分别表示接收链和产生块 
			bool flag=false;
			if(can_rec(rec,res[cur_v]))
			{
				flag=true;
				res[cur_v]=rec;
			}
			if(!add.empty()) flag=true;
			for(auto x:add) res[cur_v].push_back(x);
			if(flag) spread(cur_v,cur_t+t); //只有更新才向相邻节点传递,就是这里写成了time+t,woc真是要命 
		}
	}
	act.erase(act.begin(),act.upper_bound(time)); //将time以前的操作删除,就是这里time写成了t,要疯了! 
	cout<<res[v].size();
	for(auto ver:res[v]) cout<<" "<<ver;
	cout<<endl;
}

int main()
{
	cin>>n>>m;
	for(int i=0,a,b;i<m;i++)
	{
		cin>>a>>b;
		graph[a].push_back(b);
		graph[b].push_back(a);
	}
	for(int i=1;i<=n;i++) res[i].push_back(0);
	int k;
	cin>>t>>k;
	for(int i=0,a,b,c;i<k;i++)
	{
		cin>>a>>b;
		if(cin.get()=='\n'||cin.eof()) query(a,b); //这里是一个小技巧,判断输入的数字是2个还是3个 
		else
		{
			cin>>c;
			act[b][a][1].push_back(c);
		}
	}
} 

需要注意的是:
时间参数的选择,写的时候就要想清楚!!!45行和48行

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值