[UOJ274]温暖会指引我们前行

看春晚不如写题...

第一次写维护边权的题,因为懒所以没学边权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);
		}
	}
}

原文地址:https://www.cnblogs.com/jefflyy/p/8449773.html

时间: 2024-10-09 18:19:49

[UOJ274]温暖会指引我们前行的相关文章

【UOJ274】【清华集训2016】温暖会指引我们前行 LCT

[UOJ274][清华集训2016]温暖会指引我们前行 任务描述 虽然小R住的宿舍楼早已来了暖气,但是由于某些原因,宿舍楼中的某些窗户仍然开着(例如厕所的窗户),这就使得宿舍楼中有一些路上的温度还是很低. 小R的宿舍楼中有n个地点和一些路,一条路连接了两个地点,小R可以通过这条路从其中任意一个地点到达另外一个地点.但在刚开始,小R还不熟悉宿舍楼中的任何一条路,所以他会慢慢地发现这些路,他在发现一条路时还会知道这条路的温度和长度.每条路的温度都是互不相同的. 小R需要在宿舍楼中活动,每次他都需要从

bzoj 4736 /uoj274【清华集训2016】温暖会指引我们前行 lct

[清华集训2016]温暖会指引我们前行 统计 描述 提交 自定义测试 寒冬又一次肆虐了北国大地 无情的北风穿透了人们御寒的衣物 可怜虫们在冬夜中发出无助的哀嚎 “冻死宝宝了!” 这时 远处的天边出现了一位火焰之神 “我将赐予你们温暖和希望!” 只见他的身体中喷射出火焰之力 通过坚固的钢铁,传遍了千家万户 这时,只听见人们欢呼 “暖气来啦!” 任务描述 虽然小R住的宿舍楼早已来了暖气,但是由于某些原因,宿舍楼中的某些窗户仍然开着(例如厕所的窗户),这就使得宿舍楼中有一些路上的温度还是很低. 小R的

UOJ274 [清华集训2016] 温暖会指引我们前行 【LCT】【最大生成树】

题目分析: 差评,最大生成树裸题.hack数据还卡常. 代码: 1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 402000; 5 6 struct LCT{ 7 int fa[maxn],lazy[maxn],ch[maxn][2],d1[maxn],d2[maxn]; 8 int val[maxn],tot[maxn],num; 9 stack<int> sta; 10 void pus

UOJ 274 【清华集训2016】温暖会指引我们前行 ——Link-Cut Tree

魔法森林高清重置, 只需要维护关于t的最大生成树,然后链上边权求和即可. 直接上LCT 调了将近2h 吃枣药丸 #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define F(i,j,k) for (int i=j;i<=k;++i) #define D(i,j,k) for (int i=j;i&g

【BZOJ4736】温暖会指引我们前行(LCT)

题意:有一张图,每条边有一个不同的编号,长度和权值,维护以下操作: 1.加边 2.修改边长 3.询问两点之间在最小权值最大的前提下的唯一路径长度 n<=100000 m<=300000 思路:RYZ作业 BZOJ上有四组数据的输入不完整,输出没问题 LCT维护最大生成树,维护子树和即可和子树中权值最小的位置即可 1 var t:array[0..700000,0..1]of longint; 2 sum:array[0..700000]of int64; 3 f:array[1..700000

BZOJ 4736 温暖会指引我们前行 LCT+最优生成树+并查集

题目链接:http://uoj.ac/problem/274 题意概述: 没什么好概述的......概述了题意就知道怎么做了...... 分析: 就是用lct维护最大生成树. 然后如果去UOJ上面交发现如果不用并查集判断连通性就要T?! 然后我就默默改了并查集...(hash表并查集输入输出占据了一半的行数?!) 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdl

[清华集训] 温暖会指引我们前行

同样是LCT维护一个类似最大生成树的东西. 题目链接:戳我 emmm其实我在uoj上过不去,加的数据我TLE了...... 关于push_up的小trick:初始化的时候给0节点也初始化成最大值,然后push_up的时候不用管自己的左右儿子是否为空,直接返回左右儿子中比较小的一个就可以了,然后再和自己作比较.qwqwq 代码如下: #include<iostream> #include<cstdio> #include<cstring> #include<algo

曾指引我前行的东西

<上海交大生存手册>序言: “在上海交通大学的四年生活中,我目睹和经历了太多的荒谬,太多的错误,太多的茫然,太多的无奈,太多的失败.自诩为天之骄子的高中毕业生,站在大学的门槛上,有时竟会显得像低龄儿童一样幼稚. 年轻的同学们还未自己那充满无限可能的青春而沾沾自喜,却不曾意识到,一生仅此一张的白纸,绝不可以随意涂抹.本书希望能为同学们树立正确的人生观和价值观,并在具体政策上,提供各种切实可行的建议,帮助同学里那一部分有志青年完善自我,实现内心的追求. 回首四年大学时光,我一直保有一种强烈的对科学

我与书籍相伴的日子

与书籍相伴曾几何时,伴着"书中自有黄金屋.书中自有颜如玉"这句话,我们走过了美好的学生时代.但是,现今社会,我们不知不觉的已经与书籍渐行渐远了. 社会在进步,科技在高速发展,电子产品在飞速更新,网络已经成为了人们生活中必不可少的东西了,没有了网络,我们的衣.食.住.行都有可能陷入全面瘫痪.网络在我们的生活中起到了举足轻重的作用,它为我们的日常生活提供了极大的便利,从根本上改变了我们的生活.我们之前的阅读已经逐渐从纸质书籍演变为电子书刊,电子书刊的方便快捷不言而喻!电脑带给人们一个崭新的