• 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("");
    	}
    }
    
    
  • 相关阅读:
    tomcat启动时报:IOException while loading persisted sessions: java.io.EOFException的解决方案
    Myeclispe 安装 SVN :
    Oracle数据库中SYS、SYSTEM、DBSNMP、SYSMAN四用户的区别
    转: Maven 仓库中添加Oracle JDBC驱动(11g)
    Ubuntu14.04的常用快捷键
    Ubuntu下常用的命令
    Ubuntu14.04 java环境配置
    主谓宾定状补
    Git的常用命令
    转:Android面试
  • 原文地址:https://www.cnblogs.com/whitelily/p/13360320.html
Copyright © 2020-2023  润新知