P2173 [ZJOI2012] 网络

P2173 [ZJOI2012] 网络

题目描述

有一个无向图 G,每个点有个权值,每条边有一个颜色。这个无向图满足以下两个条件:

1、 对于任意节点连出去的边中,相同颜色的边不超过两条。

2、图中不存在同色的环,同色的环指相同颜色的边构成的环。

在这个图上,你要支持以下三种操作:

  • 0 x y 表示把节点 x 的权值改为 y

  • 1 u v w 表示将边 (u,v) 的颜色改为 w

  • 2 c u v 表示查询由颜色 c 的边构成的图中,所有可能在 uv 之间的简单路径上的节点的权值的最大值。

输入格式

第一行四个正整数 n,m,C,k,分别表示节点数、边数、颜色数和操作数。

接下来 n 行,每行一个正整数 vi,为节点 i 的权值。

之后 m 行,每行三个正整数 u,v,w,为一条连接 u,v 节点的边,颜色为w

最后 k 行,每行若干个正整数,表示一次操作。

输出格式

输出若干行,每行输出一个对应的信息。

1、 对于修改节点权值操作,不需要输出信息。

2、对于修改边的颜色操作,按以下几类输出:

  • 若不存在连接节点 u 和节点 v 的边,输出 No such edge.

  • 若修改后不满足条件 1,不修改边的颜色,并输出 Error 1.

  • 若修改后不满足条件 2,不修改边的颜色,并输出 Error 2.

  • 其他情况,成功修改边的颜色,并输出 Success.

输出满足条件的第一条信息即可,即若同时不满足条件 1,2 ,则只需要输出Error 1.

3、 对于查询操作,输出一个整数表示答案。若 u,v 之间没有颜色 c 构成的路径,则输出 1

【数据范围】

对于 100% 的数据:n104m105C10k105

1u,v,xn0c<C,保证图中没有重边和自环。

说句闲话

终于写到 LCT 了,我自己都没想到我居然欠了这么多解题报告没写,感觉今天补不完啊 QAQ.

Solution:

首先我们狠狠阅读一下题目:
1、 对于任意节点连出去的边中,相同颜色的边不超过两条。

2、图中不存在同色的环,同色的环指相同颜色的边构成的环。

C10

这启示我们针对每个颜色建一颗 LCT.然后就很板子了:

操作1我们就直接改颜色,操作二在经过一系列判断之后把原颜色的 LCT 上的边删掉,然后在新的颜色的 LCT 上加边,操作3直接 splite 就行。

操作2的“一系列操作”详见代码。

Code:

#include<bits/stdc++.h>
const int N=1e5+5;
const int C=10;
using namespace std;
int st[N];
int Max(int x,int y){return x>y ? x : y;}
int w[N];
struct LCT{
struct Tree{
int mx,val,tag,ff,ch[2];
}t[N<<2];
#define ls t[x].ch[0]
#define rs t[x].ch[1]
#define fa t[x].ff
inline bool isroot(int x)
{
return (t[fa].ch[0]==x||t[fa].ch[1]==x);
}
inline void pushup(int x)
{
t[x].mx=Max(Max(t[ls].mx,t[rs].mx),t[x].val);
return;
}
inline void rev(int x)
{
swap(t[x].ch[0],t[x].ch[1]);
t[x].tag^=1;
return ;
}
inline void pushdown(int x)
{
if(t[x].tag)
{
if(ls)rev(ls);
if(rs)rev(rs);
t[x].tag=0;
}
return ;
}
inline void rotate(int x)
{
int y=fa,z=t[fa].ff,k=t[fa].ch[1]==x ? 1 : 0;
if(isroot(y))t[z].ch[t[z].ch[1]==y]=x;
t[x].ff=z;
t[y].ch[k]=t[x].ch[!k];
if(t[x].ch[!k])t[t[x].ch[!k]].ff=y;
t[x].ch[!k]=y;
t[y].ff=x;
pushup(y);
}
inline void splay(int x)
{
int y=x,z=0;
st[++st[0]]=y;
while(isroot(y))st[++st[0]]=y=t[y].ff;
while(st[0])pushdown(st[st[0]--]);
while(isroot(x)&&x)//isn't root
{
y=fa,z=t[fa].ff;
if(isroot(y)){rotate((t[y].ch[1]==x)==(t[z].ch[1]==y) ? y : x);}
rotate(x);
}
pushup(x);
}
void access(int x)
{
int y=0;
while(x)
{
splay(x);rs=y;pushup(x);
y=x;x=fa;
}
}
void make_root(int x)//换根
{
access(x);splay(x);
rev(x);
}
int find(int x)
{
access(x);splay(x);
while(ls)pushdown(x),x=ls;
splay(x);
return x;
}
bool splite(int x,int y)
{
make_root(x);
if(find(y)!=x)return 0;
access(y);splay(y);
return 1;
}
bool link(int x,int y)// 意义很明确的函数名称
{
make_root(x);
if(find(y)!=x){t[x].ff=y;return 1;}
return 0;
}
bool cut(int x,int y)// 意义很明确的函数名称
{
make_root(x);
if(find(y)==x&&t[y].ff==x&&t[y].ch[0]==0)
{
t[y].ff=t[x].ch[1]=0;
pushup(x);
return 1;
} return 0;
}
}T[C];
int d[C][N];
int n,m,p,q;
map<pair<int,int>,int> Map;
#define mp(x,y) make_pair(x,y)
void work()
{
cin>>n>>m>>p>>q;
for(int i=1;i<=n;i++)
{
scanf("%d",&w[i]);
}
for(int j=0;j<p;j++)for(int i=1;i<=n;i++)T[j].t[i].val=T[j].t[i].mx=w[i];
for(int i=1,x,y,col;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&col);
T[col].link(x,y);d[col][x]++;d[col][y]++;
Map[mp(x,y)]=col+1;
Map[mp(y,x)]=col+1;
}
int opt,x,y,z;
for(int i=1;i<=q;i++)
{
scanf("%d%d%d",&opt,&x,&y);
if(opt==0)
{
w[x]=y;
for(int j=0;j<p;j++)
{
T[j].t[x].val=w[x];
T[j].splay(x);
}
continue;
}
scanf("%d",&z);
if(opt==1)
{
if(z==Map[mp(x,y)]-1){printf("Success.\n");continue;}
if(!Map[mp(x,y)]){printf("No such edge.\n");continue;}
if(d[z][x]==2||d[z][y]==2){printf("Error 1.\n");continue;}
if(T[z].link(x,y))
{
int col=Map[mp(x,y)]-1;Map[mp(x,y)]=Map[mp(y,x)]=z+1;
T[col].cut(x,y);
d[col][x]--,d[col][y]--;
d[z][x]++,d[z][y]++;
printf("Success.\n");
}
else {printf("Error 2.\n");}
}
if(opt==2)
{
if(T[x].splite(y,z))
{
printf("%d\n",Max(T[x].t[z].mx,T[x].t[z].val));
}
else
{
printf("%d\n",-1);
}
}
}
}
int main()
{
//freopen("network.in","r",stdin);
//freopen("network.out","w",stdout);
work();
return 0;
}
posted @   liuboom  阅读(1)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· Trae初体验
点击右上角即可分享
微信分享提示