CSP 区块链 100分

节点,边构成了图

通过邻接数组存储边集。

题意可知 ,更新会将自己的主链转发出去。

而更新有两种情况

1.添加一个新块

2.邻居传过来的主链,如果符合题目中的要求,则进行更新

重点就是如何进行更新。

可以构造一个结构体,包含到达日期,发送的主链,以及发送的对象

发送的对象是个数组比较好,这样一次转发只需要拷贝一次主链就可以了。

开始的时候80分,时间超时,改成这样后就100分,1.8s过了。

至于怎么存储这些需要更新的链,我用的multiset(因为如果根据截止日期排序,set的话会把截止日期相同的节点视作同一个节点,然后不予添加),根据截止日期进行排序

现在想想,其实链表就行,根本没必要通过set,因为是有序的。

还有一点要注意,就是题目中的bi可能跨度比较大,两个相邻的bi之间隔了很长时间,我们需要每隔一个时间单位统一接收一次可以接收的全部主链。

代码如下

#include<iostream>

#include<vector>

#include<string>

#include<map>

#include<set>

#include<queue>

#include<algorithm>

#include<cstdio>

#include<sstream>

#include<list>

using namespace std;

typedef long long ll;

typedef pair<ll,ll> pa;

int n,m;

int t,k;

vector<int> gra[505];

vector<int> ls[505];//链

struct unit{

    int ddl;//到达的时间

    vector<int> mlist;//发送的主链

    vector<int> to;

    bool operator <(const unit&t)const{

        return ddl<t.ddl;

    }

};

multiset<unit> upd;

int curtime=0;

void init()

{

    cin>>n>>m;

    for(int i=1;i<=n;i++)

        ls[i].push_back(0);

    for(int i=1;i<=m;i++){

        int from,to;

        cin>>from>>to;

        gra[from].push_back(to);

        gra[to].push_back(from);

    }

    cin>>t>>k;

    getchar();

}

void send(int a,int b);

void recv(int b)//当前时间

{

    while(1){

        auto it=upd.begin();

        if(!upd.empty()&&it->ddl<=b){//比较,然后接收

            for(auto to:it->to){

            if(ls[to].size()<it->mlist.size())

                {ls[to]=it->mlist;

                send(to,b);

                }

            else if(ls[to].size()==it->mlist.size()){

                if(it->mlist.back()<ls[to].back())

                    {ls[to]=it->mlist;

                    send(to,b);

                    }

            }

            }

            upd.erase(it);

        }

        else break;

    }

}

void send(int a,int b)//当前时间

{

    unit temp;

    temp.ddl=b+t;

    temp.mlist=ls[a];

    for(auto to:gra[a])

        temp.to.push_back(to);

    upd.insert(temp);

}

void create(int a,int b,int c)

{

    ls[a].push_back(c);

    send(a,b);

}

int main()

{   

    while(k--){

        string str;

        getline(cin,str);

        istringstream ss(str);

        int tmp;

        vector<int> temv;

        while(ss>>tmp)temv.push_back(tmp);

        int a,b,c;

        a=temv[0],b=temv[1];

        if(curtime!=b){

            for(int i=curtime;i<=b;i++)

                recv(i);

            curtime=b;

        }

        if(temv.size()==2){

            cout<<ls[a].size();

            for(auto &tmp:ls[a])

                cout<<" "<<tmp;

            cout<<"\n";

        }

        else{

            c=temv[2];

            create(a,b,c);

        }

    }

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值