ZJOI2012 网络——LCT相关题目

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

  1. 对于任意节点连出去的边中,相同颜色的边不超过两条。
  2. 图中不存在同色的环,同色的环指相同颜色的边构成的环。

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

  1. 修改一个节点的权值。
  2. 修改一条边的颜色。
  3. 查询由颜色c的边构成的图中,所有可能在节点u到节点v之间的简单路径上的节点的权值的最大值。

https://daniu.luogu.org/problem/show?pid=2173

-by luogu




对每个颜色建LCT,对error1数组记录,对error2LCT判联通性,对NO Such...直接写了hash,trie树大概开不下;

发现封装起来非常好;

代码:

  1 #include<cstdio>
  2 #include<cstring>
  3 using namespace std;
  4 int n,m,c,p;
  5 struct dt{
  6     int fa,ch[2],mark,max,num;
  7 };
  8 struct LCT{
  9     dt data[10010];
 10     int tot;
 11     void Init(){
 12         data[0].fa=data[0].mark=data[0].max=data[0].max=data[0].num=0;
 13         tot=0;
 14     }
 15     void link(int x,int y){
 16         make_root(x);data[x].fa=y;
 17     }
 18     void cut(int x,int y){
 19         make_root(x),access(y),splay(y);
 20         data[x].fa=data[y].ch[0]=0;
 21         up(y);
 22     }
 23     void access(int x){
 24         int y=0;
 25         while(x){
 26             splay(x);
 27             data[x].ch[1]=y;
 28             up(x);
 29             y=x;x=data[x].fa;
 30         }
 31     }
 32     void make_root(int x){
 33         access(x);splay(x);data[x].mark^=1;
 34     }
 35     int find_root(int x){
 36         access(x);splay(x);
 37         while(data[x].ch[0])
 38             x=data[x].ch[0];
 39         return x;
 40     }
 41     void splay(int x){
 42         push(x);
 43         int fa,fafa;
 44         for(fa=data[x].fa;data[fa].ch[1]==x||data[fa].ch[0]==x;roll(x),fa=data[x].fa){
 45             fafa=data[fa].fa;
 46             if(data[fafa].ch[1]==fa||data[fafa].ch[0]==fa)
 47                 if((data[fa].ch[0]==x)^(data[fafa].ch[0]==fa))
 48                     roll(x);
 49                 else
 50                     roll(fa);
 51         }
 52     }
 53     void roll(int now){
 54         int fa=data[now].fa,fafa=data[fa].fa,wh=data[fa].ch[1]==now;
 55         data[fa].ch[wh]=data[now].ch[wh^1];data[data[fa].ch[wh]].fa=fa;
 56         data[now].ch[wh^1]=fa;data[fa].fa=now;
 57         data[now].fa=fafa;
 58         if (data[fafa].ch[0]==fa||data[fafa].ch[1]==fa)
 59             data[fafa].ch[data[fafa].ch[1]==fa]=now;
 60         up(fa);up(now);
 61     }
 62     void push(int x){
 63         int fa=data[x].fa;
 64         if(data[fa].ch[0]==x||data[fa].ch[1]==x)
 65             push(fa);
 66         down(x);
 67     }
 68     void up(int x){
 69         int a=data[data[x].ch[0]].max>data[data[x].ch[1]].max?data[data[x].ch[0]].max:data[data[x].ch[1]].max;
 70         data[x].max=data[x].num>a?data[x].num:a;
 71     }
 72     void down(int x){
 73         int i;
 74         if(data[x].mark){
 75             i=data[x].ch[0],data[x].ch[0]=data[x].ch[1],data[x].ch[1]=i;
 76             data[x].mark=0;
 77             data[data[x].ch[0]].mark^=1;data[data[x].ch[1]].mark^=1;
 78         }
 79     }
 80 };
 81 int Hash(int ,int ,int );
 82 LCT lct[10];
 83 int col[10010][10];
 84 int hash[100000];
 85 int poll[200010],next[200010],colway[200010],tot;
 86 int main()
 87 {
 88     int i,j,k,u,v,w;
 89     scanf("%d%d%d%d",&n,&m,&c,&p);
 90     for(j=0;j<c;j++)lct[j].Init();
 91     for(i=1;i<=n;i++){
 92         scanf("%d",&k);
 93         for(j=0;j<c;j++)
 94             lct[j].data[i].num=lct[j].data[i].max=k;
 95     }
 96     for(i=1;i<=m;i++){
 97         scanf("%d%d%d",&u,&v,&w);
 98         lct[w].link(u,v);
 99         col[u][w]++;col[v][w]++;
100         Hash(u*100001+v,1,w),Hash(v*100001+u,1,w);
101     }
102     for(i=1;i<=p;i++){
103         scanf("%d",&j);
104         if(j==0){
105             scanf("%d%d",&u,&v);
106             for(k=0;k<c;k++){
107                 lct[k].splay(u);
108                 lct[k].data[u].num=v;
109                 lct[k].up(u);
110             }
111             continue;
112         }
113         if(j==1){
114             int lk;
115             scanf("%d%d%d",&u,&v,&k);
116             lk=Hash(u*100001+v,0,-1);
117             if(!lk){
118                 printf("No such edge.\n");continue;
119             }
120             if(--lk==k){
121                 printf("Success.\n");continue;
122             }
123             if(col[u][k]==2||col[v][k]==2){
124                 printf("Error 1.\n");continue;
125             }
126             lct[k].make_root(u);
127             if(lct[k].find_root(v)==u){
128                 printf("Error 2.\n");continue;
129             }
130             lct[lk].cut(u,v);
131             lct[k].link(u,v);
132             col[u][lk]--;col[v][lk]--;col[u][k]++;col[v][k]++;
133             Hash(u*100001+v,0,k);Hash(v*100001+u,0,k);
134             printf("Success.\n");continue;
135         }
136         if(j==2){
137             scanf("%d%d%d",&k,&u,&v);
138             lct[k].make_root(u);
139             if(lct[k].find_root(v)!=u){
140                 printf("-1\n");continue;
141             }
142             lct[k].access(v);
143             lct[k].splay(v);
144             printf("%d\n",lct[k].data[v].max);
145             continue;
146         }
147     }
148     return 0;
149 }
150 int Hash(int sum,int p,int color){
151     int mod=99991,x=sum%mod,i;
152     if(!hash[x]){
153         if(!p)return 0;
154         hash[x]=++tot;
155         poll[tot]=sum;colway[tot]=color;
156     }
157     else{
158         i=hash[x];
159         while(next[i]&&poll[i]!=sum)
160             i=next[i];
161         if(p){
162             next[i]=++tot;
163             poll[tot]=sum;
164             colway[tot]=color;
165             return 0;
166         }
167         if(poll[i]!=sum)return 0;
168         if(color==-1)return colway[i]+1;
169         colway[i]=color;
170     }
171     return 0;
172 }
时间: 2024-10-13 15:09:02

ZJOI2012 网络——LCT相关题目的相关文章

luoguP2173 [ZJOI2012]网络 LCT

链接 luogu 思路 颜色很少,开10个lct分别维护 if (Hash.count(make_pair(u, v)) && Hash[make_pair(u, v)] == col) {puts("Success.");continue;} 这一行的代码调了半天. 代码 #include <bits/stdc++.h> #define ls c[x][0] #define rs c[x][1] using namespace std; const int

[ZJOI2012]网络

[ZJOI2012]网络 题目 思路 显然,这是一道lct裸题.因为颜色不多,所以对于每一种颜色的边我们都建一个lct即可.(我这里是用 (颜色×n+点的标号) 表示每一种颜色lct) 操作0 因为我们对于每一种颜色的边都建了一个lct所以,我们对于每一种颜色的边都update一次.(虽然很暴力,但跑得过) 操作1 1.其实对于判断边不存在的情况,我们可以用临接矩阵来存,开一个bool数组10000*10000 128M还是开得下的.这样节约了很多时间(其实是我懒得想其它方法判断). 2.错误1

网络连接相关基础知识笔记

一.常说的TCP/IP的含义 TCP/IP协议簇并不仅仅指TCP协议和IP协议,实际它包括了一系列协议组成的集合,如:TCP,IP,UDP,FTP,SMTP,DNS,ARP,PPP等 TCP与UDP协议都属于传输层协议,但有很大不同,TCP是面向连接的协议,提供的是可靠的数据流服务,TCP采用"带重传的肯定确认"机制来实现传输的可靠性,实现了一种"虚电路",因为从物理上来说,并不是真正在两台主机间建立了连接,这种连接只是存在于逻辑上的.最大的开销出现在通信前建立连接

网络视频相关技术介绍

AnyChat音视频互动开发平台(SDK)是一套跨平台的即时通讯解决方案,基于先进的H.264视频编码标准.AAC音频编码标准与P2P技术,支持高清视频,整合了佰锐科技在音视频编码.多媒体通讯领域领先的开发技术和丰富的产品经验而设计的高质量.宽适应性.分布式.模块化的网络音视频互动平台.        AnyChat音视频互动开发平台(SDK)包含了音视频处理模块(采集.编解码).流媒体管理模块(丢包重传.抖动平滑.动态缓冲).流媒体播放模块(多路混音.音视频同步)以及P2P网络模块(NAT穿透

LeetCode: Palindrome 回文相关题目

LeetCode: Palindrome 回文相关题目汇总 LeetCode: Palindrome Partitioning 解题报告 LeetCode: Palindrome Partitioning II 解题报告 Leetcode:[DP]Longest Palindromic Substring 解题报告 LeetCode: Valid Palindrome 解题报告

linux网络配置相关文件

网络接口(interface)是网络硬件设备在操作系统中的表示方法,比如网卡在Linux操作系统中用ethX,是由0开始的正整数,比如eth0.eth1...... ethX.而普通猫和ADSL的接口是 pppX,比如ppp0等: 机器中所有可用网卡及名字: 参考:linux网络配置相关命令.虚拟网络接口eth0:0 网关GateWay配置地址: /etc/sysconfig/network  GATEWAY=192.168.1.250 /etc/sysconfig/network-script

图解几个与Linux网络虚拟化相关的虚拟网卡-VETH/MACVLAN/MACVTAP/IPVLAN

Linux的网卡驱动中内含了很多"虚拟网卡".早先的文章曾经详细分析过tun,ifb等虚拟网卡,类似的思路,在虚拟化大行其道的趋势下,Linux源码树中不断增加对"网络虚拟化"的支持,不光是为了支持"虚拟机"技术,更多的是给了用户和程序员更多的选择.       这些对网络虚拟化的支持技术包括任何重量级的虚拟化技术,比较重的比如对虚拟机技术的支持,轻量级的则是net namespace技术.近期的工作基于net namespace技术,关于这个技

九度 Online Judge 之《剑指 Offer》一书相关题目解答

前段时间准备华为机试,正好之前看了一遍<剑指 Offer>,就在九度 Online Judge 上刷了书中的题目,使用的语言为 C++:只有3题没做,其他的都做了. 正如 Linus Torvalds 所言“Talk is cheap, show me the code!",详见托管在 Github 的源码:点击打开链接(核心部分有注释). 难度总结:有些可以不必要像书中那样保存中间结果,直接输出,也就可以不使用书中的算法:有些题目在书中题目的基础上加了更多的要求,也更难实现一点.

linux网络配置相关命令、虚拟网络接口eth0:0

网络接口(interface)是网络硬件设备在操作系统中的表示方法,比如网卡在Linux操作系统中用ethX,是由0开始的正整数,比如eth0.eth1...... ethX.而普通猫和ADSL的接口是 pppX,比如ppp0等: 机器中所有可用网卡.名字.配置文件: dmesg | grep eth :可以看到系统启动时,网卡启动的信息及相应网卡的名字,然后就可以手动添加相应的/etc/sysconfig/network-scripts/ifcfg-ethX文件对网卡进行配置 ifconfig