zoukankan      html  css  js  c++  java
  • 2020牛客暑期多校训练营(第三场)G题Operating on a Graph(并查集与链表)

    2020牛客暑期多校训练营(第三场)G题Operating on a Graph(并查集与链表)

    Operating on a Graph

    题意:给一个图,q次操作,输入一个颜色op,若无op颜色则不管,否则将op相邻的颜色改为op,输出最后每个点的颜色,最开始每个点的颜色等于本身的点。

    题解:并查集比较简单,主要是不用链表或按秩合并操作会超时,因为枚举颜色最外层要一层,枚举外层每个点的颜色要一层,然后要在将那个颜色的最外层的点加入队列一层,共3层,在特例下会很慢(类似菊花连菊花,一个外层点很多的颜色,一下全部移到左边,一下全移到右边),用链表的话可以将第3层的时间变成O(1),优化很多时间。

    代码部分:

    #include<iostream>
    #include<vector>
    #include<list>
    using namespace std;
    int t,n,m,q,u,v,op,now,to;
    vector<int>ho[800007];
    list<int>lk[800007];
    int fa[800007];
    void init(){
    	for(int i=0;i<n;i++){
    		fa[i]=i;
    		ho[i].clear();
    		lk[i].clear();
    		lk[i].push_back(i);
    	}
    }
    int fin(int p){
    	if(p==fa[p])return p;
    	else{
    		return fa[p]=fin(fa[p]);
    	}
    }
    void solve(){
    	if(op!=fa[op]){
    		return;
    	}
    	int cnt=lk[op].size();
    	while(cnt--){
    		now=lk[op].front();
    		lk[op].pop_front();
    		for(int i=0;i<ho[now].size();i++){
    			to=fin(ho[now][i]);
    			if(to!=op){
    				fa[to]=op;
    				lk[op].splice(lk[op].end(),lk[to]);
    			}
    		}
    	}
    }
    int main(){
    	scanf("%d",&t);
    	while(t--){
    		scanf("%d%d",&n,&m);
    		init();
    		for(int i=1;i<=m;i++){
    			scanf("%d%d",&u,&v);
    			ho[u].push_back(v);
    			ho[v].push_back(u);
    		}
    		scanf("%d",&q);
    		while(q--){
    			scanf("%d",&op);
    			solve();
    		}
    		for(int i=0;i<n;i++){
    			printf("%d ",fin(i));
    		}
    		puts("");
    	}
    }
    
    
  • 相关阅读:
    聊聊 Java8 以后各个版本的新特性
    如何使用SpringBoot封装自己的Starter
    Git原理入门解析
    Linux磁盘管理:LVM逻辑卷的拉伸及缩减
    LVM在线扩容
    Ubuntu setup Static IP Address
    ubuntu修改主机名
    user.sh
    升级Dell的R810固件版本
    DSET收集ESXi硬件日志
  • 原文地址:https://www.cnblogs.com/whitelily/p/13360320.html
Copyright © 2011-2022 走看看