zoukankan      html  css  js  c++  java
  • 【BZOJ4668】冷战 并查集

    【BZOJ4668】冷战

    Description

    1946 年 3 月 5 日,英国前首相温斯顿·丘吉尔在美国富尔顿发表“铁幕演说”,正式拉开了冷战序幕。
    美国和苏联同为世界上的“超级大国”,为了争夺世界霸权,两国及其盟国展开了数十年的斗争。在这段时期,虽然分歧和冲突严重,但双方都尽力避免世界范围的大规模战争(第三次世界大战)爆发,其对抗通常通过局部代理战争、科技和军备竞赛、太空竞争、外交竞争等“冷”方式进行,即“相互遏制,不动武力”,因此称之为“冷战”。
    Reddington 是美国的海军上将。由于战争局势十分紧张,因此他需要时刻关注着苏联的各个活动,避免使自己的国家陷入困境。苏联在全球拥有 N 个军工厂,但由于规划不当,一开始这些军工厂之间是不存在铁路的,为了使武器制造更快,苏联决定修建若干条道路使得某些军工厂联通。
    Reddington 得到了苏联的修建日程表,并且他需要时刻关注着某两个军工厂是否联通,以及最早在修建哪条道路时会联通。具体而言,现在总共有M 个操作,操作分为两类:
    • 0 u v,这次操作苏联会修建一条连接 u 号军工厂及 v 号军工厂的铁
    路,注意铁路都是双向的;• 1 u v, Reddington 需要知道 u 号军工厂及 v 号军工厂最早在加入第几条条铁路后会联通,假如到这次操作都没有联通,则输出 0;
    作为美国最强科学家, Reddington 需要你帮忙设计一个程序,能满足他的要求。 

    Input

    第一行两个整数 N, M。
    接下来 M 行,每行为 0 u v 或 1 u v 的形式。
    数据是经过加密的,对于每次加边或询问,真正的 u, v 都等于读入的u, v 异或上上一次询问的答案。一开始这个值为 0。
    1 ≤ N, M ≤ 500000,解密后的 u, v 满足1 ≤ u, v ≤ N, u不等于v

    Output

    对于每次 1 操作,输出 u, v 最早在加入哪条边后会联通,若到这个操作时还没联通,则输出 0。 

    Sample Input

    5 9
    0 1 4
    1 2 5
    0 2 4
    0 3 4
    1 3 1
    0 7 0
    0 6 1
    0 1 6
    1 2 6

    Sample Output

    0
    3
    5

    题解:先考虑LCT做法。对于询问a,b,先判断两点是否连通,若不连通,则在a,b间连一条权值为当前时间的边。在查询时,直接将路径取出来,求路径上边权最大值即可。

    可以用并查集按秩合并实现这个过程。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    int n,m,tot,ans;
    const int maxn=500010;
    int f[maxn],d[maxn];
    int rd()
    {
    	int ret=0,f=1;	char gc=getchar();
    	while(gc<'0'||gc>'9')	{if(gc=='-')f=-f;	gc=getchar();}
    	while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();
    	return ret*f;
    }
    int main()
    {
    	n=rd(),m=rd();
    	int i,j,a,b,ta,tb,da,db;
    	for(i=1;i<=m;i++)
    	{
    		if(!rd())
    		{
    			a=rd()^ans,b=rd()^ans,da=db=0,tot++;
    			while(f[a])	a=f[a],da++;
    			while(f[b])	b=f[b],db++;
    			if(a==b)	continue;
    			if(da>db)	swap(a,b);
    			f[a]=b,d[a]=tot;
    		}
    		else
    		{
    			ta=a=rd()^ans,tb=b=rd()^ans,da=db=0,ans=0;
    			while(f[a])	a=f[a],da++;
    			while(f[b])	b=f[b],db++;
    			if(a!=b)
    			{
    				printf("0
    ");
    				continue;
    			}
    			if(da<db)	swap(ta,tb),swap(da,db);
    			a=ta,b=tb;
    			for(j=1;j<=da-db;j++)	ans=max(ans,d[a]),a=f[a];
    			while(a!=b)
    				ans=max(ans,max(d[a],d[b])),a=f[a],b=f[b];
    			printf("%d
    ",ans);
    		}
    	}
    	return 0;
    }
    //5 9 0 1 4 1 2 5 0 2 4 0 3 4 1 3 1 0 7 0 0 6 1 0 1 6 1 2 6
  • 相关阅读:
    [转发]UML类图符号 各种关系说明以及举例
    Promise 对象
    ES6基础(二)
    ES6基础
    JSON介绍
    Ajax的面试题
    Ajax请求
    jQuery从小白开始---初始jQuery
    常用的String原型
    JS之类数组
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7298698.html
Copyright © 2011-2022 走看看