版权声明:这是蒟蒻的BLOG,神犇转载也要吱一声哦~ https://blog.csdn.net/Dream_Lolita/article/details/89737867
【题目】
LG
给定一幅
个点
条边有点权,边有颜色的无向图。
有
个操作支持:
- 修改点权
- 改变边的颜色
- 询问仅看某种颜色时两点间最大点权。
若一次 操作使得某种颜色的连通块不为森林,或没有这条边,则忽略此操作并输出相应的错误信息。
,颜色数
【解题思路】
观察到颜色数很少,而每种颜色一定是一个森林。
于是每种颜色维护一个
即可。
【参考代码】
#include<bits/stdc++.h>
using namespace std;
const int N=10005;
namespace IO
{
int read()
{
int ret=0;char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) ret=ret*10+(c^48),c=getchar();
return ret;
}
void write(int x){if(x>9)write(x/10);putchar(x%10^48);}
void writeln(int x){write(x);putchar('\n');}
}
using namespace IO;
namespace Data_Structure
{
int col[N],val[N],st[N],top;
struct LCT
{
#define ls ch[x][0]
#define rs ch[x][1]
int ch[N][2],fa[N],rev[N],mx[N],du[N];
void pushup(int x){mx[x]=max(max(mx[ls],mx[rs]),val[x]);}
void pushdown(int x){if(rev[x]){rev[x]^=1;rev[ls]^=1;rev[rs]^=1;swap(ls,rs);}}
bool isroot(int x){return ch[fa[x]][0]!=x && ch[fa[x]][1]!=x;}
int get(int x){return ch[fa[x]][1]==x;}
void rotate(int x)
{
int y=fa[x],z=fa[y],k=get(x);
if(!isroot(y)) ch[z][get(y)]=x;
fa[ch[x][!k]]=y;fa[y]=x;fa[x]=z;
ch[y][k]=ch[x][!k];ch[x][!k]=y;
pushup(y);pushup(x);
}
void splay(int x)
{
st[top=1]=x;for(int t=x;!isroot(t);t=fa[t])st[++top]=fa[t];
while(top) pushdown(st[top--]);
while(!isroot(x))
{
int y=fa[x];
if(!isroot(y)) rotate(get(y)==get(x)?y:x);
rotate(x);
}
}
void access(int x){for(int y=0;x;y=x,x=fa[x])splay(x),rs=y,pushup(x);}
void makeroot(int x){access(x);splay(x);rev[x]^=1;}
int findroot(int x){access(x);splay(x);while(ls)x=ls;return x;}
void getedge(int x,int y){makeroot(x);access(y);splay(y);}
void cut(int x,int y){--du[x];--du[y];getedge(x,y);fa[x]=ch[y][0]=0;}
void link(int x,int y){++du[x];++du[y];makeroot(x);fa[x]=y;}
#undef ls
#undef rs
}T[10];
}
using namespace Data_Structure;
namespace DreamLolita
{
int n,m,C,Q;
void modifyval()
{
int x=read(),v=read();
for(int i=0;i<C;++i) T[i].access(x),T[i].splay(x);
val[x]=v;
for(int i=0;i<C;++i) T[i].pushup(x);
}
void modifyedge()
{
int x=read(),y=read(),z=read();
for(int i=0;i<C;++i) if(T[i].findroot(x)==T[i].findroot(y))
{
T[i].getedge(x,y);
if(T[i].ch[y][0]!=x || T[i].ch[x][1]) continue;
if(i==z) puts("Success.");
else if(T[z].du[x]==2 || T[z].du[y]==2) puts("Error 1.");
else if(T[z].findroot(x)==T[z].findroot(y)) puts("Error 2.");
else T[i].cut(x,y),T[z].link(x,y),puts("Success.");
return;
}
puts("No such edge.");
}
void calcans()
{
int z=read(),x=read(),y=read();
if(T[z].findroot(x)!=T[z].findroot(y)) puts("-1");
else T[z].getedge(x,y),printf("%d\n",T[z].mx[y]);
}
void solution()
{
n=read();m=read();C=read();Q=read();
for(int i=1;i<=n;++i) val[i]=read();
for(int i=1,u,v;i<=m;++i) u=read(),v=read(),T[read()].link(u,v);
while(Q--)
{
int op=read();
if(!op) modifyval();
else if(op==1) modifyedge();
else calcans();
}
}
}
int main()
{
#ifdef Durant_Lee
freopen("LGP2173.in","r",stdin);
freopen("LGP2173.out","w",stdout);
#endif
DreamLolita::solution();
return 0;
}