• UVA 3027 Corporative Network 带权并查集、


    题意:一个企业要去收购一些公司把,使的每个企业之间互联,刚开始每个公司互相独立

       给出n个公司,两种操作

       E I:询问I到I它连接点最后一个公司的距离

       I I J:将I公司指向J公司,也就是J公司是I公司的上级,距离为abs(I-J)%1000(貌似G++不支持abs,PE了两发)

    思路:转化一下题意就行了,首先刚开始的时候每个公司都是独立的,I操作就是并查集中合并操作,将I这课树并到J这个树上,

       E操作要求的东西就是 I到I的根节点的距离,先看一个没有路径压缩直接暴力的方法把、(本以为不会过的,因为数据很大)

        时间是:2222ms  被系统藐视了

      等等,现已题目中所给的例子来把 直接执行完I 操作 ,最后得到的是  3->1->2->4

        那么E 3所得到的结果是 (3-1)%1000+(2-1)%1000+(4-2)%1000=5

      并查集本身就是这样的结果,所以直接从子节点向根节点找过去,一边找一遍求距离

      

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    const int qq=20000+5;
    int pre[qq],sum[qq];
    int ans;
    void init(int n)
    {
    	for(int i = 0; i <= n; ++i){
    		pre[i]=i;
    		sum[i]=0;
    	}
    }
    int find(int x)
    {
    	if(x==pre[x])	return x;
    	else{
    		int dis=x-pre[x]>0?x-pre[x]:pre[x]-x;
    		dis%=1000;
    		ans+=dis;
    		return find(pre[x]);
    	}
    }
    int main()
    {
    	int t,n;scanf("%d",&t);
    	while(t--){
    		scanf("%d",&n);
    		init(n);
    		char s[10];
    		while(scanf("%s",s) && (s[0]!='O')){
    			if(s[0] == 'E'){
    				int a;
    				scanf("%d",&a);
    				ans = 0;
    				find(a);
    				printf("%d
    ",ans);
    			}
    			else if(s[0] == 'I'){
    				int a,b;
    				scanf("%d%d",&a,&b);			
    					pre[a] = b;
    			}
    		}
    	}
    	return 0;
    } 
    

    路径压缩版、 66MS

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    const int qq=20000+5;
    int pre[qq],dis[qq];
    int ans;
    void init(int n)
    {
    	for(int i = 0; i <= n; ++i){		//初始化、 
    		pre[i]=i;
    		dis[i]=0;
    	}
    }
    int find(int x)				//只想说递归的调用真的很神奇,然而我还是个半桶水 
    {
    	if(x==pre[x])	return x;
    	int flag=find(pre[x]);		// 在find函数中直接进行路径压缩 
    	dis[x]=dis[x]+dis[pre[x]];	// 一边压缩一遍更新子节点到根节点的距离值 
    	return pre[x]=flag;			//这里是压缩路径、 
    }
    int main()
    {
    	int t,n;scanf("%d",&t);
    	while(t--){
    		scanf("%d",&n);
    		init(n);
    		char s[10];
    		while(scanf("%s",s) && (s[0]!='O')){
    			if(s[0] == 'E'){
    				int a;
    				scanf("%d",&a);
    				find(a);		//对于要找的那个a,在此之前去压缩路径并更新到根节点的距离值 
    				printf("%d
    ",dis[a]);
    			}
    			else if(s[0] == 'I'){
    				int a,b;
    				scanf("%d%d",&a,&b);
    				pre[a]=b;			// 合并 
    				int ans=a-b>0?a-b:b-a;
    				ans%=1000;		//求距离、 
    				dis[a]=ans;		//然后赋值 
    			}
    		}
    	}
    	return 0;
    } 
    

     

  • 相关阅读:
    解读AppIcon图标设置置信息和App内存警告临界值
    我在外包公司做增删改查有前途么?
    浅议Grpc传输机制和WCF中的回调机制的代码迁移
    2019.NET Conf China(中国.NET开发者峰会)活动全纪录:.NET技术之崛起,已势不可挡
    一位年轻而优秀的.NET开发者的成长点滴
    领域驱动设计-让程序员心中有码(九)
    2019.NET Conf,我们在共同期待
    码农的技术小世界
    .NET Core使用gRPC打造服务间通信基础设施
    坚持写了一年的博客,我有哪些收获
  • 原文地址:https://www.cnblogs.com/sasuke-/p/5293604.html
Copyright © 2020-2023  润新知