• 【BZOJ2816】【ZJOI2012】网络(Link-Cut Tree)


    【BZOJ2816】【ZJOI2012】网络(Link-Cut Tree)

    题面

    题目描述

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

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

    图中不存在同色的环,同色的环指相同颜色的边构成的环。
    在这个图上,你要支持以下三种操作:

    修改一个节点的权值。

    修改一条边的颜色。

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

    输入输出格式

    输入格式:
    输入文件network.in的第一行包含四个正整数N, M, C, K,其中N为节点个数,M为边数,C为边的颜色数,K为操作数。

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

    之后M行,每行三个正整数u, v, w,为一条连接节点u和节点v的边,颜色为w。满足1 ≤ u, v ≤ N,0 ≤ w < C,保证u ≠ v,且任意两个节点之间最多存在一条边(无论颜色)。

    最后K行,每行表示一个操作。每行的第一个整数k表示操作类型。

    k = 0为修改节点权值操作,之后两个正整数x和y,表示将节点x的权值vx修改为y。

    k = 1为修改边的颜色操作,之后三个正整数u, v和w,表示将连接节点u和节点v的边的颜色修改为颜色w。满足0 ≤ w < C。

    k = 2为查询操作,之后三个正整数c, u和v,表示查询所有可能在节点u到节点v之间的由颜色c构成的简单路径上的节点的权值的最大值。如果不存在u和v之间不存在由颜色c构成的路径,那么输出“-1”。
    输出格式:
    输出文件network.out包含若干行,每行输出一个对应的信息。

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

    对于修改边的颜色操作,按以下几类输出:
    a) 若不存在连接节点u和节点v的边,输出“No such edge.”。

    b) 若修改后不满足条件1,不修改边的颜色,并输出“Error 1.”。

    c) 若修改后不满足条件2,不修改边的颜色,并输出“Error 2.”。

    d) 其他情况,成功修改边的颜色,并输出“Success.”。

    输出满足条件的第一条信息即可,即若同时满足b和c,则只需要输出“Error 1.”。

    对于查询操作,直接输出一个整数。

    输入输出样例

    输入样例#1:
    4 5 2 7
    1
    2
    3
    4
    1 2 0
    1 3 1
    2 3 0
    2 4 1
    3 4 0
    2 0 1 4
    1 1 2 1
    1 4 3 1
    2 0 1 4
    1 2 3 1
    0 2 5
    2 1 1 4
    输出样例#1:
    4
    Success.
    Error 2.
    -1
    Error 1.
    5

    题解

    考虑(C<=10)
    那么, 暴力维护(C)棵树即可
    直接(LCT)维护即可
    细节真的是有点多。。。
    这道题目慢慢做。。。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define MAX 11000
    #define fat t[x].ff
    #define lson t[x].ch[0]
    #define rson t[x].ch[1]
    inline int read()
    {
        int x=0,t=1;char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return x*t;
    }
    int S[MAX],top;
    struct N{int u,v;};
    int n,m,C,K,val[MAX];
    int color[MAX][11];
    bool operator<(N a,N b)
    {
    	if(a.u!=b.u)return a.u<b.u;
    	return a.v<b.v;
    }
    map<N,int> MM;
    struct Node
    {
    	int ch[2],ff;
    	int mm,val,rev; 
    };
    struct LCT
    {
    	struct Node t[MAX];
    	void pushup(int x){t[x].mm=max(t[lson].mm,t[rson].mm);t[x].mm=max(t[x].mm,t[x].val);}
    	bool isroot(int x){return t[fat].ch[0]!=x&&t[fat].ch[1]!=x;}
    	void pushdown(int x)
    	{
    		if(!t[x].rev)return;
    		swap(lson,rson);
    		t[lson].rev^=1;t[rson].rev^=1;
    		t[x].rev^=1;
    	}
    	void rotate(int x)
    	{
    		int y=t[x].ff,z=t[y].ff;
    		int k=t[y].ch[1]==x;
    		if(!isroot(y))t[z].ch[t[z].ch[1]==y]=x;t[x].ff=z;
    		t[y].ch[k]=t[x].ch[k^1];t[t[x].ch[k^1]].ff=y;
    		t[x].ch[k^1]=y;t[y].ff=x;	
    		pushup(y);pushup(x);	
    	}
    	void Splay(int x)
    	{
    		S[top=1]=x;
    		for(int i=x;!isroot(i);i=t[i].ff)S[++top]=t[i].ff;
    		while(top)pushdown(S[top--]);
    		while(!isroot(x))
    		{
    			int y=t[x].ff,z=t[y].ff;
    			if(!isroot(y))
    				(t[y].ch[0]==x)^(t[z].ch[0]==y)?rotate(x):rotate(y);
    			rotate(x);
    		}
    	}
    	void access(int x){for(int y=0;x;y=x,x=t[x].ff)Splay(x),t[x].ch[1]=y,pushup(x);}
    	void makeroot(int x){access(x);Splay(x);t[x].rev^=1;}
    	void split(int x,int y){makeroot(x);access(y);Splay(y);}
    	void cut(int x,int y){split(x,y);t[y].ch[0]=t[x].ff=0;}
    	void link(int x,int y){makeroot(x);t[x].ff=y;}
    	int findroot(int x){access(x);Splay(x);while(lson)x=lson;return x;}
    }LCT[11];
    int main()
    {
        n=read();m=read();C=read();K=read();
        for(int i=1;i<=n;++i)val[i]=read();
        for(int i=1;i<=n;++i)
        	for(int j=1;j<=C;++j)
        		LCT[j].t[i].val=val[i];
        for(int i=1,u,v,w;i<=m;++i)
        {
        	u=read(),v=read(),w=read()+1;
        	MM[(N){u,v}]=w;
        	MM[(N){v,u}]=w;
        	color[u][w]++;color[v][w]++;
        	LCT[w].link(u,v);
        }
        while(K--)
        {
        	int opt=read();
        	if(opt==0)
        	{
        		int x=read();val[x]=read();
        		for(int i=1;i<=C;++i)
        		{
        			LCT[i].access(x);
        			LCT[i].Splay(x);
    				LCT[i].t[x].val=val[x];
    			}
        	}
        	else if(opt==1)
        	{
        		int u=read(),v=read(),w=read()+1;
        		int G=MM[(N){u,v}];
        		if(!G){puts("No such edge.");continue;}
        		if(G==w){puts("Success.");continue;}
    			if(color[u][w]>1||color[v][w]>1){puts("Error 1.");continue;}
        		if(LCT[w].findroot(u)==LCT[w].findroot(v)){puts("Error 2.");continue;}
        		color[u][w]++;color[v][w]++;
        		color[u][G]--;color[v][G]--;
        		MM[(N){u,v}]=w;MM[(N){v,u}]=w;
        		LCT[G].cut(u,v);
        		LCT[w].link(u,v);
        		puts("Success.");
    		}
        	else
        	{
        		int w=read()+1,u=read(),v=read();
        		if(LCT[w].findroot(u)!=LCT[w].findroot(v)){puts("-1");continue;}
        		LCT[w].split(u,v);
        		printf("%d
    ",LCT[w].t[v].mm);
        	}
        }
        return 0;
    }
    
  • 相关阅读:
    java基础的第二轮快速学习!day08
    java基础的第二轮快速学习!day07
    java基础的第二轮快速学习!day06
    Jsp复习(详细的知识点)day01
    Struts2,大爷你好!第二天补一发笔记
    java基础的第二轮快速学习!day05
    Struts2,大爷你好!第二天
    java基础的第二轮快速学习!day04
    Struts2,大爷你好!第一天
    java基础的第二轮快速学习!day03
  • 原文地址:https://www.cnblogs.com/cjyyb/p/7954289.html
Copyright © 2020-2023  润新知