[NOI2018]归程

description

题面

data range

[nle 200000,m,kle 400000 ]

solution

(Kruskal)重构树

甚至比[ONTAK2010]Peaks加强版还要容易码

不再多说

code

为什么我写了个叫(Dij)的函数,一开始写的却是(SPFA)...

习惯很难改啊

#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<iomanip>
#include<cstring>
#include<complex>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<ctime>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define FILE "a"
#define mp make_pair
#define pb push_back
#define RG register
#define il inline
using namespace std;
typedef unsigned long long ull;
typedef vector<int>VI;
typedef long long ll;
typedef double dd;
const dd eps=1e-10;
const int mod=1e9+7;
const int N=400010;
const int M=400010;
const dd pi=acos(-1);
const int inf=2147483645;
const ll INF=1e18+1;
const ll P=100000;
il ll read(){
	RG ll data=0,w=1;RG char ch=getchar();
	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
	if(ch=='-')w=-1,ch=getchar();
	while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
	return data*w;
}

il void file(){
	srand(time(NULL)+rand());
	freopen("1.in","r",stdin);
	freopen(FILE".out","w",stdout);
}

int num,n,m,q,k,s,ans;
struct edge{int u,v,w;}E[M];
bool cmp_w(edge x,edge y){return x.w>y.w;}
int head[N],to[N<<1],nxt[N<<1],val[N<<1],cnt;
il void add(int u,int v,int w){
	to[++cnt]=v;
	nxt[cnt]=head[u];
	val[cnt]=w;
	head[u]=cnt;
}

struct node{
	int id,x;
	bool operator <(const node &b)const{return x>b.x;}
};
priority_queue<node>Q;
int dis[N];bool vis[N];
il void Dijaaaaaaaaaaaaaaa(){
	for(RG int i=1;i<=n;i++)dis[i]=inf,vis[i]=0;
	while(!Q.empty())Q.pop();
	dis[1]=0;Q.push((node){1,0});
	for(RG int t=1;t<=n;t++){
		RG node x=Q.top();Q.pop();
		while(vis[x.id]){
			if(Q.empty())break;
			x=Q.top();Q.pop();
		}
		if(vis[x.id]&&Q.empty())break;
		RG int u=x.id;vis[u]=1;
		for(RG int i=head[u];i;i=nxt[i]){
			RG int v=to[i];
			if(!vis[v]&&dis[v]>dis[u]+val[i]){
				dis[v]=dis[u]+val[i];Q.push((node){v,dis[v]});
			}
		}
	}
}

int fa[N];
int find(int x){return fa[x]?fa[x]=find(fa[x]):x;}

int h[N],RT,f[20][N];
void dfs(int u,int ff){
	f[0][u]=ff;
	for(RG int i=1;f[i-1][f[i-1][u]];i++)f[i][u]=f[i-1][f[i-1][u]];
	for(RG int i=head[u];i;i=nxt[i]){
		RG int v=to[i];dfs(v,u);
	}
}

il int solve(int v,int p){
	RG int u=v;
	for(RG int i=19;~i;i--)
		if(f[i][u]&&h[f[i][u]]>p)u=f[i][u];
	return dis[u];
}

int main()
{
	RG int T=read();
	while(T--){
		memset(head,0,sizeof(head));
		memset(fa,0,sizeof(fa));
		memset(f,0,sizeof(f));
		cnt=ans=0;
		
		num=n=read();m=read();
		for(RG int i=1,u,v,l,a;i<=m;i++){
			u=read();v=read();l=read();a=read();
			E[i]=(edge){u,v,a};
			add(u,v,l);add(v,u,l);
		}
		
		Dijaaaaaaaaaaaaaaa();
		
		memset(head,0,sizeof(head));cnt=0;
		sort(E+1,E+m+1,cmp_w);
		for(RG int i=1;i<=m;i++)
			if(find(E[i].u)!=find(E[i].v)){
				RG int x=find(E[i].u),y=find(E[i].v);
				h[++num]=E[i].w;
				fa[x]=fa[y]=num;dis[num]=min(dis[x],dis[y]);
				add(num,x,0);add(num,y,0);
			}
		RT=find(1);dfs(RT,0);

		q=read();k=read();s=read();
		for(RG int i=1,v,p;i<=q;i++){
			v=(read()+k*ans-1)%n+1;
			p=(read()+k*ans)%(s+1);
			printf("%d
",ans=solve(v,p));
		}
	}
	return 0;
}

原文地址:https://www.cnblogs.com/cjfdf/p/9498937.html