• CSP模拟58联测20 注视一切的终结


    题目大意

    给定一个 n n n个点 m m m条边的无向连通图,每条边有颜色 w i w_i wi。保证这个图存在自环和长度大于 2 2 2且经过每个点一次的环,也就是说删除所有重边后图就变成了一棵树。

    假设一条简单路径(路径上的各顶点均不互相重复)先后经过的边为 a 1 , a 2 , ⋯   , a k a_1,a_2,\cdots,a_k a1,a2,,ak,定义这条路径的权值为 ( w a 1 ≠ w a 2 ) + ( w a 2 + w a 3 ) + ⋯ + ( w a k − 1 + w a k ) (w_{a_1}\neq w_{a_2})+(w_{a_2}+w_{a_3})+\cdots+(w_{a_{k-1}}+w_{a_k}) (wa1=wa2)+(wa2+wa3)++(wak1+wak)

    q q q次询问,每次询问给出两个点 x , y x,y x,y,求 x x x y y y的所有简单路径的权值最大值。

    1 ≤ n , q ≤ 5 × 1 0 5 , 1 ≤ m ≤ 1 0 6 , 1 ≤ w i ≤ m 1\leq n,q\leq 5\times 10^5,1\leq m\leq 10^6,1\leq w_i\leq m 1n,q5×105,1m106,1wim

    时间限制 4000 m s 4000ms 4000ms,空间限制 1024 M B 1024MB 1024MB


    题解

    首先,如果一条边有大于等于三种颜色(我们把重边看作同一条边),则这条边一定有一种颜色与路径上其他两条边的颜色不同。所以,对于每条边,我们只需保留至多三种颜色。

    为了方便,我们将每条边保存在其深度较大的端点 x x x中,也就是每个点保存其连向父亲的边的颜色。边的第 i i i种颜色记为 c l x , i cl_{x,i} clx,i

    考虑用倍增来解决问题。设 g x , t , i , j g_{x,t,i,j} gx,t,i,j表示从点 x x x往上跳 2 t 2^t 2t步,跳到的点靠近 x x x的边为第 i i i种颜色,另一端的边为第 j j j种颜色时的最大权值。

    g g g的初始值为 g x , 0 , i , j = [ c l x , i ≠ c l f a , j ] g_{x,0,i,j}=[cl_{x,i}\neq cl_{fa,j}] gx,0,i,j=[clx,i=clfa,j],其中 f a fa fa x x x的父亲。

    对于每个点 x x x,在转移时,令 y = f x , t − 1 , z = f x , t y=f_{x,t-1},z=f_{x,t} y=fx,t1,z=fx,t f x , t f_{x,t} fx,t表示 x x x向上跳 2 t 2^t 2t步到达的点),枚举 x , y , z x,y,z x,y,z的颜色 i , j , k i,j,k i,j,k,则转移式为

    g x , t , i , k = max ⁡ { g x , t − 1 , i , j + g y , t − 1 , j , k } g_{x,t,i,k}=\max\{g_{x,t-1,i,j}+g_{y,t-1,j,k}\} gx,t,i,k=max{gx,t1,i,j+gy,t1,j,k}

    对于每个查询的点 x , y x,y x,y,先分别求出这两个点到 l c a lca lca的在与 l c a lca lca的连边选择不同颜色的最大权值 c x cx cx c y cy cy,转移与上面类似。如果其中一点为 l c a lca lca,则答案就是这些选择不同颜色的最大权值中的最大值;否则,枚举两条与 l c a lca lca的连边的颜色, a n s = max ⁡ { c x i + c y j + [ c l t x , i = = c l t y , j ] } ans=\max\{cx_i+cy_j+[cl_{tx,i}==cl_{ty,j}]\} ans=max{cxi+cyj+[cltx,i==clty,j]},其中 t x tx tx x x x l c a lca lca路径上 l c a lca lca的前一个点, t y ty ty y y y l c a lca lca路径上 l c a lca lca的前一个点。

    时间复杂度为 O ( 3 3 n log ⁡ n + 3 2 q log ⁡ n ) O(3^3n\log n+3^2q\log n) O(33nlogn+32qlogn)

    code

    #include
    #define lc k<<1
    #define rc k<<1|1
    using namespace std;
    const int N=500005,M=1000000;
    int n,m,q,tot=0,d[2*M+5],l[2*M+5],r[2*M+5],w[2*M+5],z[N+5];
    int ans,ct[N+5],cl[N+5][4],dep[N+5],f[N+5][20],g[N+5][20][4][4];
    void add(int xx,int yy,int zz){
    	l[++tot]=r[xx];d[tot]=yy;r[xx]=tot;w[tot]=zz;
    }
    void dfs1(int u,int fa){
    	if(z[u]) return;
    	z[u]=1;
    	for(int i=r[u];i;i=l[i]){
    		if(d[i]==fa){
    			if(ct[u]<3){
    				int fl=1;
    				for(int j=1;j<=ct[u];j++){
    					if(w[i]==cl[u][j]) fl=0;
    				}
    				if(fl) cl[u][++ct[u]]=w[i];
    			}
    			continue;
    		}
    		dfs1(d[i],u);
    	}
    }
    void dfs2(int u,int fa){
    	if(z[u]==2) return;
    	z[u]=2;
    	dep[u]=dep[fa]+1;
    	f[u][0]=fa;
    	if(u>1){
    		for(int i=1;i<=ct[u];i++){
    			for(int j=1;j<=ct[fa];j++){
    				g[u][0][i][j]=(cl[u][i]!=cl[fa][j]);
    			}
    		}
    	}
    	for(int t=1;(1<<t)<=dep[u];t++){
    		f[u][t]=f[f[u][t-1]][t-1];
    		int y=f[u][t-1],z=f[u][t];
    		for(int i=1;i<=ct[u];i++){
    			for(int j=1;j<=ct[y];j++){
    				for(int k=1;k<=ct[z];k++){
    					g[u][t][i][k]=max(g[u][t][i][k],g[u][t-1][i][j]+g[y][t-1][j][k]);
    				}
    			}
    		}
    	}
    	for(int i=r[u];i;i=l[i]){
    		if(d[i]==fa) continue;
    		dfs2(d[i],u);
    	}
    }
    int gtlca(int x,int y){
    	if(dep[x]<dep[y]) swap(x,y);
    	for(int i=19;i>=0;i--){
    		if(dep[f[x][i]]>=dep[y]) x=f[x][i];
    	}
    	if(x==y) return x;
    	for(int i=19;i>=0;i--){
    		if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
    	}
    	return f[x][0];
    }
    int gt(int x,int y,int *c){
    	int cc[4];
    	c[1]=c[2]=c[3]=0;
    	for(int t=19;t>=0;t--){
    		if(dep[f[x][t]]>dep[y]){
    			cc[1]=cc[2]=cc[3]=0;
    			for(int i=1;i<=ct[x];i++){
    				for(int j=1;j<=ct[f[x][t]];j++){
    					cc[j]=max(cc[j],c[i]+g[x][t][i][j]);
    				}
    			}
    			c[1]=cc[1];c[2]=cc[2];c[3]=cc[3];
    			x=f[x][t];
    		}
    	}
    	return x;
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1,x,y,z;i<=m;i++){
    		scanf("%d%d%d",&x,&y,&z);
    		add(x,y,z);add(y,x,z);
    	}
    	dfs1(1,0);
    	dfs2(1,0);
    	scanf("%d",&q);
    	for(int o=1;o<=q;o++){
    		int x,y,lca,tx=0,ty=0,cx[4],cy[4];
    		scanf("%d%d",&x,&y);
    		lca=gtlca(x,y);
    		if(x!=lca) tx=gt(x,lca,cx);
    		if(y!=lca) ty=gt(y,lca,cy);
    		ans=0;
    		if(x==lca){
    			for(int i=1;i<=ct[ty];i++) ans=max(ans,cy[i]);
    		}
    		else if(y==lca){
    			for(int i=1;i<=ct[tx];i++) ans=max(ans,cx[i]);
    		}
    		else{
    			for(int i=1;i<=ct[tx];i++){
    				for(int j=1;j<=ct[ty];j++){
    					ans=max(ans,cx[i]+cy[j]+(cl[tx][i]!=cl[ty][j]));
    				}
    			}
    		}
    		printf("%d\n",ans);
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
  • 相关阅读:
    L84.linux命令每日一练 -- 第11章 Linux系统管理命令 -- rpm和yum
    R在GIS中用ggmap地理空间数据分析
    python 各种画图(2D 3D)-1 _matplotlib 官方网站笔记
    蚁群优化算法在具有时间窗的车辆路径问题中的应用:MATLAB实现及详解
    在群晖NAS部署_开源在线项目任务管理工具【dooTask】
    云计算项目十一:构建完整的日志分析平台
    Docker容器常用命令笔记分享
    泰森多边形
    京东平台API接口
    爬虫与反爬虫技术简介
  • 原文地址:https://blog.csdn.net/tanjunming2020/article/details/133913382