[ZJOI2012][bzoj 2816] 网络 network [LCT]

题目:

http://www.lydsy.com/JudgeOnline/problem.php?id=2816

思路:

第一个条件看完暂时还没什么想法

看完第二个,发现每一个颜色都是一个森林

进而想到对于每一个颜色维护LCT

看数据范围,n<=10000, c<=10,可行

对于操作0,把每一个LCT上该店的权值都修改

对于操作1,先检测这条边是否存在,若不存在就No such edge

如果这条边存在,且原来的颜色不同于要修改的颜色的话,就先判断Error 1和Error 2

如果要改的边已经是目标颜色了,就特判跳过

上述判断都通过了就cut和link即可

对于操作2,每一个节点维护一个最大值,输出即可

Code:

  1 /**************************************************************
  2     Problem: 2816
  3     User: dedicatus545
  4     Language: C++
  5     Result: Accepted
  6     Time:8032 ms
  7     Memory:6688 kb
  8 ****************************************************************/
  9
 10 #include<iostream>
 11 #include<cstdio>
 12 #include<algorithm>
 13 #include<cstring>
 14 #include<unistd.h>
 15 #define col(i,c) n*c+i
 16 using namespace std;
 17 inline int read(){
 18     int re=0,flag=1;char ch=getchar();
 19     while(ch>‘9‘||ch<‘0‘){
 20         if(ch==‘-‘) flag=-1;
 21         ch=getchar();
 22     }
 23     while(ch>=‘0‘&&ch<=‘9‘) re=(re<<1)+(re<<3)+ch-‘0‘,ch=getchar();
 24     return re*flag;
 25 }
 26 struct edge{
 27     int to,next,w;
 28 }e[200010];
 29 int n,m,C,cnt=-1,q,first[100010],color[10010][11];
 30 int fa[100010]={0},ch[100010][2]={0},w[100010],a[100010];
 31 bool rev[100010]={0},rt[100010]={0};
 32 void _swap(int &l,int &r){l^=r;r^=l;l^=r;}
 33 void update(int x){a[x]=max(a[ch[x][0]],max(a[ch[x][1]],w[x]));};
 34 void pushrev(int x){
 35     if(!x) return;
 36     _swap(ch[x][0],ch[x][1]);
 37     rev[x]^=1;
 38 }
 39 void pushdown(int x){
 40     if(!x) return;
 41     if(rev[x]){
 42         pushrev(ch[x][0]);
 43         pushrev(ch[x][1]);
 44         rev[x]=0;
 45     }
 46 }
 47 void push(int x){
 48     //cout<<"push "<<x<<‘ ‘<<rt[x]<<‘\n‘;
 49     if(!x) sleep(1000);
 50     if(!rt[x]) push(fa[x]);
 51     pushdown(x);
 52 }
 53 int get(int x){return ch[fa[x]][1]==x;}
 54 void rotate(int x){
 55     //cout<<"rotate "<<x<<‘\n‘;
 56     int f=fa[x],ff=fa[f],son=get(x);
 57     ch[f][son]=ch[x][son^1];
 58     if(ch[f][son]) fa[ch[f][son]]=f;
 59     ch[x][son^1]=f;fa[f]=x;
 60     fa[x]=ff;
 61     if(rt[f]) rt[x]=1,rt[f]=0;
 62     else ch[ff][ch[ff][1]==f]=x;
 63     update(f);update(x);
 64 }
 65 void splay(int x){
 66     //cout<<"splay "<<x<<‘\n‘;
 67     push(x);
 68     for(int f;!rt[x];rotate(x))
 69         if(!rt[f=fa[x]])
 70             rotate((get(x)==get(f))?f:x);
 71     update(x);
 72 }
 73 void access(int x){
 74     //cout<<"access "<<x<<‘\n‘;
 75     int y=0;
 76     do{
 77         splay(x);
 78         rt[ch[x][1]]=1;
 79         rt[ch[x][1]=y]=0;
 80         x=fa[y=x];
 81         update(x);
 82     }while(x);
 83 }
 84 void makeroot(int x){
 85     //cout<<"makeroot "<<x<<‘\n‘;
 86     access(x);splay(x);pushrev(x);
 87 }
 88 bool judge(int x,int y){
 89     while(fa[x]) x=fa[x];
 90     while(fa[y]) y=fa[y];
 91     return x==y;
 92 }
 93 void init(int x,int y){
 94     //cout<<"init "<<x<<‘ ‘<<y<<‘\n‘;
 95     makeroot(x);fa[x]=y;
 96 }
 97 int link(int x,int y){
 98     if(judge(x,y)) return 0;
 99     makeroot(x);fa[x]=y;
100     return 1;
101 }
102 int cut(int x,int y){
103     if(!judge(x,y)) return 0;
104     makeroot(x);splay(y);
105     fa[ch[y][0]]=fa[y];
106     rt[ch[y][0]]=1;
107     fa[y]=0;ch[y][0]=0;
108     return 1;
109 }
110 void add(int u,int v,int w){
111     e[++cnt]=(edge){v,first[u],w};first[u]=cnt;
112     e[++cnt]=(edge){u,first[v],w};first[v]=cnt;
113 }
114 int split(int u,int v){
115     if(!judge(u,v)) return -1;
116     makeroot(u);access(v);splay(v);
117     return a[v];
118 }
119 int main(){
120    // freopen("networkzj.in","r",stdin);
121   //  freopen("networkzj.out","w",stdout);
122     memset(first,-1,sizeof(first));
123     int i,j,t1,t2,t3,t4;
124     n=read();m=read();C=read();q=read();
125     for(i=1;i<=n;i++){
126         t1=read();
127         for(j=0;j<C;j++) a[col(i,j)]=w[col(i,j)]=t1,rt[col(i,j)]=1;
128     }
129
130     for(i=1;i<=m;i++){
131         t1=read();t2=read();t3=read();
132         init(col(t1,t3),col(t2,t3));
133         add(t1,t2,t3);
134         color[t1][t3]++;color[t2][t3]++;
135     }
136     //for(i=1;i<=n;i++){
137         //for(j=0;j<C;j++) cout<<color[i][j]<<‘ ‘;
138         //cout<<‘\n‘;
139     //}
140     for(i=1;i<=q;i++){
141         //cout<<"operation "<<i<<‘\n‘;
142         t1=read();
143         if(t1==0){
144             t2=read();t3=read();
145             for(j=0;j<C;j++){
146                 makeroot(col(t2,j));w[col(t2,j)]=t3;update(col(t2,j));
147             }
148         }
149         if(t1==1){
150             t2=read();t3=read();t4=read();bool flag=1,f=1;
151             for(j=first[t2];~j;j=e[j].next)
152                 if(e[j].to==t3){
153                     flag=0;
154                     if(e[j].w==t4) f=0;
155                 }
156             if(flag){
157                 printf("No such edge.\n");
158                 continue;
159             }
160             if(f&&(color[t2][t4]==2||color[t3][t4]==2)){
161                 printf("Error 1.\n");continue;
162             }
163             if(f&&(judge(col(t2,t4),col(t3,t4)))){
164                 printf("Error 2.\n");continue;
165             }
166             for(j=first[t2];~j;j=e[j].next){
167                 if(e[j].to==t3){
168                     color[t2][e[j].w]--;color[t3][e[j].w]--;
169                     cut(col(t2,e[j].w),col(t3,e[j].w));
170                     e[j].w=e[j^1].w=t4;
171                     color[t2][t4]++;color[t3][t4]++;
172                     link(col(t2,t4),col(t3,t4));
173                     printf("Success.\n");break;
174                 }
175             }
176         }
177         if(t1==2){
178             t2=read();t3=read();t4=read();
179             printf("%d\n",split(col(t3,t2),col(t4,t2)));
180         }
181     }
182 }

原文地址:https://www.cnblogs.com/dedicatus545/p/8387511.html

时间: 2024-11-13 08:17:44

[ZJOI2012][bzoj 2816] 网络 network [LCT]的相关文章

AC日记——[ZJOI2012]网络 bzoj 2816

2816 思路: 多个LCT: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 10005 #define ll long long int val[maxn]; struct LinkCutTreeType { int f[maxn],Max[maxn],ch[maxn][2],rev[maxn],sta[maxn],top,cnt[maxn]; void updata(int now) { Max[now]=va

bzoj 2816: [ZJOI2012]网络(splay)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2816 [题意] 给定一个无向图,满足条件:从一个节点出发的同色边不超过2条,且不存在同色环.要求提供修改节点权值,修改边的颜色,查询同色边c构成的图中u->v路径上节点的最大权值. [思路] 根据满足的条件,可以判断同色的图构成了若干条一条链. 考虑使用splay维护这些链: 对于每个图上的点建C个splay结点.这里需要splay提供将结点u旋转到根的操作,所以需要维护一个fa指针

bzoj 1834: [ZJOI2010]network 网络扩容 -- 最大流+费用流

1834: [ZJOI2010]network 网络扩容 Time Limit: 3 Sec  Memory Limit: 64 MB Description 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不扩容的情况下,1到N的最大流: 2. 将1到N的最大流增加K所需的最小扩容费用. Input 输入文件的第一行包含三个整数N,M,K,表示有向图的点数.边数以及所需要增加的流量. 接下来的M行每行包含四个整数u,v,C,W,表示一

[bzoj2816][ZJOI2012]网络(LCT,splay)

传送门 题解 话说以前还真没见过用LCT只维护一条链的……好像除了树点涂色那题…… 先看一下题目规定的两个性质 对于任意节点连出去的边中,相同颜色的边不超过两条. 图中不存在同色的环,同色的环指相同颜色的边构成的环. 很明显了,同一种颜色肯定是由几条链组成的(虽然我根本没有发现) 然后又要查询边权和维护路径……直接上LCT吧 然后颜色数很少啊……每一个颜色开一个LCT好了 更改权值的话在每一个LCT上splay一下 修改颜色的话在原来的LCT中cut,新的LCT中link 查询路径直接split

bzoj:1834: [ZJOI2010]network 网络扩容

Description 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不扩容的情况下,1到N的最大流: 2. 将1到N的最大流增加K所需的最小扩容费用. Input 输入文件的第一行包含三个整数N,M,K,表示有向图的点数.边数以及所需要增加的流量. 接下来的M行每行包含四个整数u,v,C,W,表示一条从u到v,容量为C,扩容费用为W的边. Output 输出文件一行包含两个整数,分别表示问题1和问题2的答案. Sample Inpu

BZOJ 1834 ZJOI2010 network 网络扩展 Dinic+EK费用流

标题效果:给定一个n积分m无向图边,每一方有一个扩展的成本c.代表扩张1费用的交通,寻求最大流量和扩大的最大流量k最小成本 第一问直接运行的最大流量 第二个问题将是连接到一个流的末端每个边缘的起点是正无穷大.费用c缘 然后,n汇点被连接到流动ans+k 费用为0的边 跑最小费用最大流就可以 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 5

[BZOJ 1834][ZJOI2010]network 网络扩容(费用流)

Description 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不扩容的情况下,1到N的最大流: 2. 将1到N的最大流增加K所需的最小扩容费用. Solution 先求出最大流maxflow 求最小扩容费用的话,对于每一条边,建一条容量为c费用为0的边,再建一条容量为INF费用为w的边 跑费用流求流入maxflow+k的费用 #include<iostream> #include<cstdio> #include

BZOJ 1834 ZJOI2010 network 网络扩容 Dinic+EK费用流

题目大意:给定一个n个点m条边的无向图,每条边有一个扩容费用c,代表每扩容1流量的花费,求最大流及将最大流扩大k的最小费用 第一问直接跑最大流 第二问将每条边的起始点向终点连接一条流量为正无穷.费用为c的边 然后将n向汇点连一条流量为ans+k 费用为0的边 跑最小费用最大流即可 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 5010 #

[BZOJ 3282] Tree 【LCT】

题目链接:BZOJ - 3282 题目分析 这道题是裸的LCT,包含 Link , Cut 和询问两点之间的路径信息. 写代码时出现的错误:Access(x) 的循环中应该切断的是原来的 Son[x][1] ,然而我写成了 Son[x][0] ! 代码 #include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <cmath> #incl