1. 程式人生 > >[UOJ274]溫暖會指引我們前行

[UOJ274]溫暖會指引我們前行

void turn clas 最大 row pla swa div utm

看春晚不如寫題...

第一次寫維護邊權的題,因為懶所以沒學邊權lct,寫的是插入虛點存邊權,但我猜兩種寫法的效率應該差不多

要求最低溫度盡量高,所以只能走最高溫度生成樹上的邊,用lct維護就行了

lct維護最大生成樹,每加一條邊$\left(x,y,T\right)$,如果兩邊不連通就直接連,如果連通且樹上$x\rightarrow y$的最低溫度$\geq T$,那麽不用加邊,否則刪掉樹上路徑最低溫的邊,加入新邊

個人覺得這種插入虛點維護邊權的寫法挺方便的

#include<stdio.h>
int ch[400010][2],fa[400010],r[400010],t[400010],l[400010],mn[400010],mp[400010],s[400010];
#define ls ch[x][0]
#define rs ch[x][1]
void pushup(int x){
	s[x]=s[ls]+s[rs]+l[x];
	mn[x]=t[x];
	mp[x]=x;
	if(ls&&mn[ls]<mn[x]){
		mn[x]=mn[ls];
		mp[x]=mp[ls];
	}
	if(rs&&mn[rs]<mn[x]){
		mn[x]=mn[rs];
		mp[x]=mp[rs];
	}
}
void swap(int&a,int&b){a^=b^=a^=b;}
void rev(int x){
	r[x]^=1;
	swap(ls,rs);
}
void pushdown(int x){
	if(r[x]){
		if(ls)rev(ls);
		if(rs)rev(rs);
		r[x]=0;
	}
}
bool isrt(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
void gao(int x){
	if(!isrt(x))gao(fa[x]);
	pushdown(x);
}
void rot(int x){
	int y,z,f,B;
	y=fa[x];
	z=fa[y];
	f=(ch[y][0]==x);
	B=ch[x][f];
	fa[x]=z;
	fa[y]=x;
	if(B)fa[B]=y;
	ch[x][f]=y;
	ch[y][f^1]=B;
	if(ch[z][0]==y)ch[z][0]=x;
	if(ch[z][1]==y)ch[z][1]=x;
	pushup(y);
	pushup(x);
}
void splay(int x){
	int y,z;
	gao(x);
	while(!isrt(x)){
		y=fa[x];
		z=fa[y];
		if(!isrt(y))rot((ch[z][0]==y&&ch[y][0]==x)||(ch[z][1]==y&&ch[y][1]==x)?y:x);
		rot(x);
	}
}
void access(int x){
	int y=0;
	while(x){
		splay(x);
		rs=y;
		pushup(x);
		y=x;
		x=fa[x];
	}
}
void makert(int x){
	access(x);
	splay(x);
	rev(x);
}
bool cn(int x,int y){
	if(x==y)return 1;
	makert(x);
	access(y);
	splay(y);
	return fa[x]!=0;
}
void link(int x,int y){
	makert(x);
	fa[x]=y;
}
void modify(int x,int v){
	splay(x);
	l[x]=v;
	pushup(x);
}
int query(int x,int y){
	if(!cn(x,y))return-1;
	makert(x);
	access(y);
	splay(y);
	return s[y];
}
int querymin(int x,int y){
	makert(x);
	access(y);
	splay(y);
	return mn[y];
}
void cutmin(int x,int y){
	makert(x);
	access(y);
	splay(y);
	x=mp[y];
	splay(x);
	fa[ls]=fa[rs]=0;
}
void link(int id,int x,int y,int T,int L){
	if(cn(x,y)){
		if(querymin(x,y)>=T)return;
		cutmin(x,y);
	}
	mn[id]=t[id]=T;
	s[id]=l[id]=L;
	mp[id]=id;
	link(x,id);
	link(id,y);
}
int main(){
	int n,m,i,u,v,t,l;
	char s[10];
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;i++)mn[i]=::t[i]=1000000000;
	while(m--){
		scanf("%s",s);
		if(s[0]==‘f‘){
			scanf("%d%d%d%d%d",&i,&u,&v,&t,&l);
			i++;
			u++;
			v++;
			link(i+n,u,v,t,l);
		}
		if(s[0]==‘m‘){
			scanf("%d%d",&u,&v);
			u++;
			v++;
			printf("%d\n",query(u,v));
		}
		if(s[0]==‘c‘){
			scanf("%d%d",&i,&l);
			i++;
			modify(i+n,l);
		}
	}
}

[UOJ274]溫暖會指引我們前行