[bzoj4777]Switch Grass
结论:最短路径一定是单独的一条边且在最小生成树上,可以用反证法证明。
那么求出最小生成树,对于每一个点建立一棵权值线段树,再对每一个权值线段树上的叶子节点开一个multiset,维护所有儿子中该种颜色的权值(普通节点仍维护区间最小值),答案也需要用multiset维护。
1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 200005
4 #define mid (l+r>>1)
5 multiset<int>ans,s[N*3];
6 struct ji{
7 int nex,to,len;
8 }edge[N<<1];
9 struct ji2{
10 int x,y,z;
11 bool operator < (const ji2 &k)const{
12 return z<k.z;
13 }
14 }a[N];
15 int E,V,V2,n,m,q,head[N],f[N],r[N],sh[N],id[N*29],ls[N*29],rs[N*29],tr[N*29],c[N];
16 int find(int k){
17 if (k==f[k])return k;
18 return f[k]=find(f[k]);
19 }
20 void add(int x,int y,int z){
21 edge[E].nex=head[x];
22 edge[E].to=y;
23 edge[E].len=z;
24 head[x]=E++;
25 }
26 void update(int &k,int l,int r,int x,int y,int p,int c){
27 if ((!k)&&(y==-1))return;
28 if (!k)k=++V;
29 if (l==r){
30 if (!id[k])id[k]=++V2;
31 if (y!=-1)
32 if (p==1)s[id[k]].insert(y);
33 else s[id[k]].erase(s[id[k]].find(y));
34 if ((c==x)||(!s[id[k]].size()))tr[k]=0x3f3f3f3f;
35 else tr[k]=(*s[id[k]].begin());
36 return;
37 }
38 if (x<=mid)update(ls[k],l,mid,x,y,p,c);
39 else update(rs[k],mid+1,r,x,y,p,c);
40 tr[k]=min(tr[ls[k]],tr[rs[k]]);
41 }
42 void dfs(int k,int fa){
43 f[k]=fa;
44 for(int i=head[k];i!=-1;i=edge[i].nex)
45 if (edge[i].to!=fa){
46 dfs(edge[i].to,k);
47 sh[edge[i].to]=edge[i].len;
48 update(r[k],1,n,c[edge[i].to],edge[i].len,1,c[k]);
49 }
50 ans.insert(tr[r[k]]);
51 }
52 int main(){
53 scanf("%d%d%*d%d",&n,&m,&q);
54 memset(head,-1,sizeof(head));
55 tr[0]=0x3f3f3f3f;
56 for(int i=1;i<=m;i++)scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
57 sort(a+1,a+m+1);
58 for(int i=1;i<=n;i++)f[i]=i;
59 for(int i=1;i<=m;i++)
60 if (find(a[i].x)!=find(a[i].y)){
61 f[find(a[i].x)]=find(a[i].y);
62 add(a[i].x,a[i].y,a[i].z);
63 add(a[i].y,a[i].x,a[i].z);
64 }
65 for(int i=1;i<=n;i++)scanf("%d",&c[i]);
66 dfs(1,0);
67 int x,y;
68 for(int i=1;i<=q;i++){
69 scanf("%d%d",&x,&y);
70 if (f[x]){
71 ans.erase(ans.find(tr[r[f[x]]]));
72 update(r[f[x]],1,n,c[x],sh[x],-1,c[f[x]]);
73 update(r[f[x]],1,n,y,sh[x],1,c[f[x]]);
74 ans.insert(tr[r[f[x]]]);
75 }
76 ans.erase(ans.find(tr[r[x]]));
77 update(r[x],1,n,c[x],-1,1,y);
78 c[x]=y;
79 update(r[x],1,n,c[x],-1,1,c[x]);
80 ans.insert(tr[r[x]]);
81 printf("%d\n",(*ans.begin()));
82 }
83 }
[bzoj4777]Switch Grass的更多相关文章
- BZOJ 4777: [Usaco2017 Open]Switch Grass
4777: [Usaco2017 Open]Switch Grass Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 46 Solved: 10[Su ...
- BZOJ4777 [Usaco2017 Open]Switch Grass[最小生成树+权值线段树套平衡树]
标题解法是吓人的. 图上修改询问,不好用数据结构操作.尝试转化为树来维护.发现(不要问怎么发现的)最小生成树在这里比较行得通,因为最近异色点对一定是相邻的(很好想),所以只要看最短的一条两端连着异色点 ...
- Luogu 3665 [USACO17OPEN]Switch Grass 切换牧草
BZOJ 4777 被权限了. 这道题的做法看上去不难,但是感觉自己yy不出来. 首先是两个结论: 1.答案一定是连接着两个异色点的一条边. 2.答案一定在最小生成树上. 感觉看到了之后都比较显然,自 ...
- BZOJ 4777 Usaco2017 Open Switch Grass Kruskal+替罪羊树+权值线段树
这道题首先可以看出答案一定是一条边,而且答案一定在最小生成树上,那么我们就可以在这个最小生成树上维护他与异色儿子的边最小值,所以我们就可以已通过Kruskal和一棵平衡树来解决,时间复杂度是O(n*l ...
- P3665 [USACO17OPEN]Switch Grass
题目描述 N个点M条边的无向图,每个点有一个初始颜色,每次改变一个点的颜色,求改变后整张图上颜色不同的点之间的距离最小值. 思路 考虑整张图的距离最小值一定是一条边,而不可能是一条路径,那么显然这条边 ...
- USACO 2017 US Open
只会做T1,FallDream T2 n^2暴力AC,太强啦. T1.Modern Art 题目大意:有一个n*n的矩阵,一开始都是0,你有n^2种颜色,编号1到n^2,每次可以选出一种颜色涂满一个子 ...
- 游戏编程算法与技巧 Game Programming Algorithms and Techniques (Sanjay Madhav 著)
http://gamealgorithms.net 第1章 游戏编程概述 (已看) 第2章 2D图形 (已看) 第3章 游戏中的线性代数 (已看) 第4章 3D图形 (已看) 第5章 游戏输入 (已看 ...
- Partition:分区切换(Switch)
在SQL Server中,对超级大表做数据归档,使用select和delete命令是十分耗费CPU时间和Disk空间的,SQL Server必须记录相应数量的事务日志,而使用switch操作归档分区表 ...
- java中if和switch哪个效率快
首先要看一个问题,if 语句适用范围比较广,只要是 boolean 表达式都可以用 if 判断:而 switch 只能对基本类型进行数值比较.两者的可比性就仅限在两个基本类型比较的范围内.说到基本类型 ...
随机推荐
- Java(24)常用API三
作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15228417.html 博客主页:https://www.cnblogs.com/testero ...
- Install WSL
Install WSL Prerequisites You must be running Windows 10 version 2004 and higher (Build 19041 and hi ...
- 2020BUAA软工个人项目作业
2020BUAA软工个人项目作业 17373010 杜博玮 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 个人项目作业 我在这个课程的目标是 学 ...
- 架构师之路-redis集群解析
引子 上篇<架构师之路-https底层原理>里我提到了上面的整体视图,文章也介绍了想要真正能在工作中及时正确解决问题的基本功:原理理解透彻.今天以redis集群解析为例介绍一个及时敏锐的发 ...
- cf 24 Game (观察+.. 想一想)
题意: 给一个数N,从1到N. 每次取两个数,三种操作:加.减.乘,运算完得一个数,把那俩数删了,把这个数加进去. 重复操作N-1次. 问是否可能得到24.若可以,输出每一步操作. 思路: 小于4,不 ...
- Go 日常开发常备第三方库和工具
不知不觉写 Go 已经快一年了,上线了大大小小好几个项目:心态也经历了几轮变化. 因为我个人大概前五年时间写的是 Java ,中途写过一年多的 Python,所以刚接触到 Go 时的感觉如下图: 既没 ...
- Win10下C语言转8086汇编
目录 Win10下C语言转8086汇编 简介 开始 写C代码 转换成汇编代码 Win10下C语言转8086汇编 简介 最近学习<王爽汇编>,然后突发奇想,想一边写C语言用编译器将其翻译成汇 ...
- UVA1104 Chips Challenge
一.题目 有一个 \(n\times n\) 的矩阵,每个元素可能是 ..C./ 的其中一种,分别表示可以放置芯片.已经放置了芯片.不能放置芯片,你可以分别决定是否可以放置芯片的位置放置芯片. 最后需 ...
- conda无法导入,pip可以导入
在conda中创建测试的虚拟环境 进入test虚拟环境,输入命令:conda install keras 输入命令python,进入python环境,输入import keras 返回错误,No mo ...
- c++ IO库
1:为了支持使用宽字符的语言,标准库定义了一组类型和对象来操作wchar_t类型的数据.宽字符版本的类型和函数的名字以w开头.宽字符版本和普通的char版本定义在同一个头文件中,例如头文件fstrea ...