合理的结构很重要!
遇到时序问题时,可以用小根堆来存事件发生顺序,再一个个弹出执行。
满分代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=510;
vector<int> g[maxn];
vector<vector<int> > l;
vector<int> last[maxn];
int n,m,t,k;
int a,b,c;
struct node
{
int t,id,fid,hid;//发生时间,当前节点编号,父节点编号,待更新的链标号
bool operator<(const node&r) const
{
return t>r.t;
}
};
int head[maxn];//每个点的主链是哪条
priority_queue<node> q;//小根堆存待更新的点
void operation()
{
auto tmp=q.top();
q.pop();
int u=tmp.id;
int fa=tmp.fid;
int hv=tmp.hid;
auto &x=l[head[u]],&y=l[hv];
if(x.size()<y.size()||((x.size()==y.size())&&x.back()>y.back()))
{
head[u]=hv;
for(int i=0;i<g[u].size();i++)
{
int v=g[u][i];
if(v!=u&&fa!=v)
{
q.push({tmp.t+t,v,u,hv});
}
}
}
}
void add(int a,int b)
{
g[a].push_back(b);
g[b].push_back(a);
}
int main()
{
//ios::sync_with_stdio(0);用了此加速就不能用fgets了
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int a,b;
cin>>a>>b;
add(a,b);
}
l.push_back({0});
cin>>t>>k;
getchar();
char str[100];
while(k--)
{
//特殊处理一下未知个数数据
fgets(str, 100, stdin);
stringstream ssin(str);
int in[3], cnt = 0;
while (ssin >> in[cnt]) cnt ++ ;
//cout<<cnt<<endl;
if(cnt==3)
{ //cout<<"!"<<endl;
a=in[0],b=in[1],c=in[2];//点,时间,新块
while(q.size()&&q.top().t<=b)//先把该时间之前的全部处理完
{
operation();
}
l.push_back(l[head[a]]);
l.back().push_back(c);
head[a]=l.size()-1;
for(int i=0;i<g[a].size();i++)
{
int v=g[a][i];
if(v!=a)
q.push({b+t,v,a,head[a]});
}
//q.push({b+t,a});
}
if(cnt==2)
{
a=in[0],b=in[1];//查询点、时间
while(q.size()&&q.top().t<=b)//先把该时间之前的全部处理完
{
operation();
}
cout<<l[head[a]].size()<<' ';
for(int i=0;i<l[head[a]].size();i++) cout<<l[head[a]][i]<<' ';
cout<<endl;
}
}
return 0;
}