题目很鸡儿长,就是个模拟,时间给了10s,数据的话不是特别大,考虑用vector来模拟这个'链'。
数据给的也很规整,可以说很良心了,时间都是按序给出的。
做法是维护一个更新队列q,里面的信息是在t时刻有一个对cur号节点的更新操作,来自于fa号节点,且fa号节点对应的链为id号。显然q里面t是递增的。
维护一个‘链’的vector h,h里面每一个元素就是一个'链',好处在于我们根据下标就可以定位到链,且保存了每个节点所有‘链’的状态,保证了后面的更新操作。
每次询问/add之前都要看下q里面对于当前时间之前的更新是否都考虑完了才可以。特别要提示的是,更新操作具有传递性,例如1->2->3,假如1号节点在cur时刻更新了,
那么2号在cur+t,3号在cur+t+t时刻考虑更新,我们只需在2号考虑完之后在传递给他的邻居就完成了这一点。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 #define inf 0x3f3f3f3f 5 #define pii pair<int,int> 6 struct node{ 7 int t,id,cur,fa; 8 }; 9 const int maxn=505; 10 int f[maxn][maxn]; 11 vector<int>g[maxn]; 12 int N,M; 13 int a,b,c,t,k; 14 int data[maxn]; 15 vector<vector<int> > h; 16 queue<node>q;//<ti,id> 17 int main(){ 18 int u,v; 19 ios::sync_with_stdio(false); 20 memset(f,0,sizeof(f)); 21 cin>>N>>M; 22 h.push_back(vector<int>(1,0)); 23 for(int i=1;i<=N;++i)data[i]=0; 24 for(int i=1;i<=M;++i){ 25 cin>>u>>v; 26 f[u][v]=f[v][u]=1; 27 } 28 for(int i=1;i<=N;++i){ 29 for(int j=1;j<=N;++j){ 30 if(i!=j&&f[i][j]){ 31 g[i].push_back(j); 32 } 33 } 34 } 35 cin>>t>>k; 36 string str;getline(cin,str); 37 while(k--){ 38 bool update=0; 39 c=-1; 40 getline(cin,str); 41 stringstream ss(str); 42 ss>>a;ss>>b; 43 if(ss.str().size())ss>>c; 44 //处理b时刻之前的操作 45 while(!q.empty() && q.front().t<=b){ 46 node nd=q.front();q.pop(); 47 int ti=nd.t,id=nd.id,v=nd.cur,fa=nd.fa; 48 if(h[id].size()<h[data[v]].size() || 49 (h[id].size()==h[data[v]].size() && h[id].back()>=h[data[v]].back()) )continue; 50 else{ 51 data[v]=id; 52 update=1; 53 } 54 for(int vv:g[v]){ 55 if(vv==fa)continue; 56 q.push(node{ti+t,id,vv,v}); 57 } 58 } 59 if(c==-1){ 60 cout<<h[data[a]].size(); 61 for(int v:h[data[a]])cout<<' '<<v;cout<<endl; 62 }else{ 63 vector<int>tmp=h[data[a]]; 64 tmp.push_back(c); 65 h.push_back(tmp); 66 data[a]=h.size()-1; 67 update=1; 68 } 69 if(update){ 70 for(int v:g[a]){ 71 q.push(node{b+t,data[a],v,a}); 72 } 73 } 74 } 75 return 0; 76 }