致敬传奇 Kruskal 重构树题硬控我三小时

NOI2018 归程

  1. 存边的数组拿来干两件事,忘了清空了,其实最好开两个的
  2. dfs 没开 vis 导致不知道为什么出现的绕圈
  3. 倍增的 fa[i][j] 定义的时候前面是 \(2^{i}\) 写着写着记错成后面了
  4. 忘记要递减排序了,跑的最小生成树
  5. 并查集没初始化
  6. 不知道为什么,倍增的 fa 数组单独一块处理会 WA,回来发现是因为只循环到 n,没处理虚点,不过这个时候我已经把它塞到 dfs 里对了
  7. 忘记删输出中间变量
  8. 忘记删 freopen
  9. 并查集忘记路径压缩

因为破防了,特此记录

#include<bits/stdc++.h>
using namespace std;
const int N=800001;
int n,m;
struct edge{
	int to,w;
};
vector<edge>e[N];
struct aedge{
	int x,y,l;
	bool operator <(const aedge &A)const{
		return l>A.l;
	}
}E[N];
struct node{
	int id,w;
	bool operator <(const node &A)const{
		return w>A.w;
	}
};
int fa[N][21],mn[N],val[N];
namespace dsu{
	int fa[N];
	void clear(int n){
		for(int i=1;i<=n;++i){
			fa[i]=i;
		}
	}
	int find(int id){
//		cout<<"find "<<id<<endl;
		if(id==fa[id]) return id;
		fa[id]=find(fa[id]);
		return fa[id];
	}
}
namespace DIJKSTRA{
	int vis[N],dis[N];
	priority_queue<node>q;
	void dij(){
		memset(vis,0,sizeof vis);
		memset(dis,0x3f,sizeof dis);
		vis[1]=1;dis[1]=0;
		q.push({1,dis[1]});
		while(!q.empty()){
			node u=q.top();q.pop();
			for(edge i:e[u.id]){
				if(dis[i.to]>dis[u.id]+i.w){
					dis[i.to]=dis[u.id]+i.w;
					q.push({i.to,dis[i.to]});
				}
			}
		}
	}
}
bool vvis[N];
void dfs(int now,int last){
	if(vvis[now]) return;
	vvis[now]=true;
//	cout<<"dfs "<<now<<" "<<last<<endl;
//	cout<<"dfs "<<now<<" "<<last<<endl;
	fa[now][0]=last;
	mn[now]=DIJKSTRA::dis[now];
//	cout<<now<<" "<<mn[now]<<endl;
	for(int i=1;i<=20;++i){
		fa[now][i]=fa[fa[now][i-1]][i-1];
	}
	for(edge i:e[now]){
		if(i.to!=last){
			dfs(i.to,now);
			mn[now]=min(mn[now],mn[i.to]);
		}
	}
}
int cnt;
int main(){
//	freopen("in.in","r",stdin);
//	freopen("1.out","w",stdout); 
	int cases;scanf("%d",&cases);while(cases--){
		scanf("%d %d",&n,&m);
		memset(mn,0,sizeof mn);
		memset(fa,0,sizeof fa);
		for(int i=1;i<=N;++i){
			e[i].clear();
		}
		for(int i=1;i<=m;++i){
			int x,y,l,a;scanf("%d %d %d %d",&x,&y,&l,&a);
			E[i]={x,y,a};
			e[x].push_back({y,l});
			e[y].push_back({x,l});
//			cout<<"add "<<x<<" "<<y<<endl;
//			cout<<"add "<<y<<" "<<x<<endl;
		}
//		cout<<"aa "<<endl;
		DIJKSTRA::dij();
//		cout<<"aa "<<endl;
		sort(E+1,E+m+1);
//		cout<<"aa "<<endl;
		dsu::clear(N);
		for(int i=1;i<=N;++i){
			e[i].clear();
		}
//		cout<<"aa "<<endl;
		int now=n;
		for(int i=1;i<=m;++i){
//			cout<<"aa "<<i<<endl;
//			cout<<E[i].x<<" "<<E[i].y<<endl;
			int x=E[i].x,y=E[i].y,w=E[i].l;
			int fx=dsu::find(x);
//			cout<<"fx"<<endl;
			int fy=dsu::find(y);
//			cout<<"fy"<<endl;
			if(fx^fy){
				val[++now]=w;
//				cout<<"你他妈到底在哪RE了"<<endl;
				dsu::fa[fx]=dsu::fa[fy]=dsu::fa[now]=now;
//				cout<<"6"<<endl;
				e[now].push_back({fx,1});
//				cout<<"6"<<endl;
				e[now].push_back({fy,1});
//				cout<<"add "<<now<<" "<<fx<<endl;
//				cout<<"add "<<now<<" "<<fy<<endl;
//				cout<<"6"<<endl;
			}
		}
//		cout<<"dfs"<<endl;
		memset(vvis,false,sizeof vvis);
		dfs(now,0);
		int last=0;
//		cout<<"54"<<endl;
		int q,k,s;scanf("%d %d %d",&q,&k,&s);
		for(int i=1;i<=q;++i){
			int x,y,v,p;
			scanf("%d %d",&x,&y);
			v=(x+k*last-1)%n+1;
			p=(y+k*last)%(s+1);
			for(int j=20;j>=0;--j){
				if(fa[v][j] and val[fa[v][j]]>p) v=fa[v][j];
			}
//			cout<<"find "<<v<<endl;
			printf("%d\n",last=mn[v]);
		}
	}
}
posted @ 2024-07-26 20:20  HaneDaniko  阅读(22)  评论(0编辑  收藏  举报