[jzoj]3875.【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)
Link
https://jzoj.net/senior/#main/show/3875
Problem
在遥远的S星系中一共有N个星球,编号为1…N。其中的一些星球决定组成联盟,以方便相互间的交流。
但是,组成联盟的首要条件就是交通条件。初始时,在这N个星球间有M条太空隧道。每条太空隧道连接两个星球,使得它们能够相互到达。若两个星球属于同一个联盟,则必须存在一条环形线路经过这两个星球,即两个星球间存在两条没有公共隧道的路径。
为了壮大联盟的队伍,这些星球将建设P条新的太空隧道。这P条新隧道将按顺序依次建成。一条新轨道建成后,可能会使一些星球属于同一个联盟。你的任务是计算出,在一条新隧道建设完毕后,判断这条新轨道连接的两个星球是否属于同一个联盟,如果属于同一个联盟就计算出这个联盟中有多少个星球。
Solution
题目太长也太烦,幼稚而又没智商。
题目大意是:“给你n个点,m条边,给出p个询问,每个询问给出一条边,先连这条边,然后判断两个点是否处在环内,是的话就输出环的大小”
我们考虑使用一种方便计算答案的连边方式
对于输入的m+p条边,我们每次连的边,要符合以下条件才连
连了这条边,不会让图中有环。
为什么这样连是对的呢?因为连了对答案没有任何贡献。
怎么判环呢?用并查集判断两点祖先是否相同,并给祖先之间连一条边。
根据这个判定条件连完边,整个图,就是一个森林(很多树)。
在之后的判断里,如果这条边在有判定条件的那次连边中连过了,那说明他怎么连都不会构成环,所以输出No。
然后,再对之前没有连的边处理。我们设当前没有连的边为x~y
那么,连了这个边一定会构成一个环,这个环的大小,其实就是求x~lca(x,y)+y~lca(x,y)的长度,可以看下面的图。(红色代表边x~y,其中,黑色圈圈住的部分即环的大小)
找出了答案后,我们进行缩点处理。
因为这环中每一个点的答案,都是一样的,所以,我们可以把答案存在lca这个点上,在之后的询问中,如果遇到这个环中的点,就跳到lca的地方去。这个操作,同样用并查集操作。把环中的点,他们的father,直接赋值为lca。但是,不是将他们的祖先赋值为lca的祖先上去。
每次我们找到一个点,我们直接跳到他f数组中的父亲上,以免重复计算同一个环上的数值。
如果一个在执行操作时,一个环中套一个环,那么先形成的环,他的父亲通过并查集,一定赋值为后形成的环的父亲,故只计算一次。
大概流程:每次模拟找lca,然后跳到当前点并查集中的父亲上,知道跳到他们的lca,计算答案。
Code
打得很臭,也很丑,见谅
{$inline on}
var
n,m,p,i,j,x,y,xx,yy,tot,ans,lca:longint;
bz:array[..] of boolean;
a:array[..,..] of longint;
l,pre,d:array[..] of longint;
f,re,dad,dis,shen,have:array[..] of longint;
procedure insert(x,y:longint); inline;
begin
inc(tot);
d[tot]:=y;
pre[tot]:=l[x];
l[x]:=tot;
end;
function getfather(x:longint):longint; inline;
begin
if f[x]= then exit(x);
f[x]:=getfather(f[x]);
exit(f[x]);
end;
procedure he(x,y:longint); inline;
var
fx,fy:longint;
begin
fx:=getfather(x);
fy:=getfather(y);
if fx<>fy then
f[fx]:=fy;
end;
procedure build(x,num,q:longint); inline;
var
k:longint;
begin
dad[x]:=q;
shen[x]:=num;
k:=l[x];
while k<> do
begin
if dis[d[k]]= then
begin
dis[d[k]]:=;
build(d[k],num+,x);
end;
k:=pre[k];
end;
end;
procedure check(var x,y:longint); inline;
begin
while shen[x]<>shen[y] do
begin
while shen[x]>shen[y] do
begin
ans:=ans+re[x];
inc(have[]);
have[have[]]:=x;
x:=dad[x];
x:=getfather(x);
end;
while shen[x]<shen[y] do
begin
ans:=ans+re[y];
inc(have[]);
have[have[]]:=y;
y:=dad[y];
y:=getfather(y);
end;
end;
end;
begin
readln(n,m,p);
for i:= to m+p do
begin
readln(x,y);
if getfather(x)<>getfather(y) then
begin
he(x,y);
insert(x,y);
insert(y,x);
bz[i]:=true;
end;
a[i,]:=x;
a[i,]:=y;
end;
for i:= to n do
if dis[i]= then
begin
dis[i]:=;
build(i,,i);
end;
fillchar(f,sizeof(f),);
for i:= to n do
re[i]:=;
for i:= to m do
begin
if bz[i] then
continue;
x:=getfather(a[i,]);
y:=getfather(a[i,]);
ans:=;
have[]:=;
check(x,y);
while x<>y do
begin
ans:=ans+re[x]+re[y];
inc(have[]);
have[have[]]:=x;
inc(have[]);
have[have[]]:=y;
x:=dad[x];
y:=dad[y];
x:=getfather(x);
y:=getfather(y);
check(x,y);
end;
ans:=ans+re[x];
re[x]:=ans;
for j:= to have[] do
begin
f[have[j]]:=x;
re[have[j]]:=ans;
end;
end;
/////////////////////////////////////////////////////////////
for i:=m+ to m+p do
begin
if bz[i] then
begin
writeln('No');
continue;
end;
x:=getfather(a[i,]);
y:=getfather(a[i,]);
ans:=;
have[]:=;
check(x,y);
while x<>y do
begin
ans:=ans+re[x]+re[y];
inc(have[]);
have[have[]]:=x;
inc(have[]);
have[have[]]:=y;
x:=dad[x];
y:=dad[y];
x:=getfather(x);
y:=getfather(y);
check(x,y);
end;
ans:=ans+re[x];
re[x]:=ans;
writeln(ans);
for j:= to have[] do
begin
f[have[j]]:=x;
re[have[j]]:=ans;
end;
end;
end.
[jzoj]3875.【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)的更多相关文章
- 【JZOJ3875】【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)
fg 在遥远的S星系中一共有N个星球,编号为1-N.其中的一些星球决定组成联盟,以方便相互间的交流. 但是,组成联盟的首要条件就是交通条件.初始时,在这N个星球间有M条太空隧道.每条太空隧道连接两个星 ...
- 【JZOJ3873】【NOIP2014八校联考第4场第2试10.20】乐曲创作(music)
ujfuiaty 小可可是音乐学院的一名学生,他需要经常创作乐曲完成老师布置的作业. 可是,小可可是一个懒惰的学生.所以,每次完成作业时,他不会重新创作一首新的乐曲,而是去修改上一次创作过的乐曲作为作 ...
- 【JZOJ3852】【NOIP2014八校联考第2场第2试9.28】单词接龙(words)
DDD Bsny从字典挑出N个单词,并设计了接龙游戏,只要一个单词的最后两个字母和另一个单词的前两个字母相同,那么这两个单词就可以有序的连接起来. Bsny想要知道在所给的所有单词中能否按照上述方式接 ...
- 【JZOJ3853】【NOIP2014八校联考第2场第2试9.28】帮助Bsny(help)
EVRT Bsny的书架乱成一团了,帮他一下吧! 他的书架上一共有n本书,我们定义混乱值是连续相同高度书本的段数.例如,如果书的高度是30,30,31,31,32,那么混乱值为3:30,32,32,3 ...
- 【JZOJ3854】【NOIP2014八校联考第2场第2试9.28】分组(group)
MEi Bsny所在的精灵社区有n个居民,每个居民有一定的地位和年龄,ri表示第i个人的地位,ai表示第i个人的年龄. 最近社区里要举行活动,要求几个人分成一个小组,小组中必须要有一个队长,要成为队长 ...
- 11.6八校联考T1,T2题解
因为版权问题,不丢题面,不放代码了(出题人姓名也隐藏) T1 这,是一道,DP题,但是我最开始看的时候,我思路挂了,以为是一道简单题,然后就写错了 后来,我正确理解题意后写了个dfs,幸亏没有记忆化, ...
- 三校联考 Day3
三校联考 Day3 大水题 题目描述:给出一个圆及圆上的若干个点,问两个点间的最远距离. solution 按极角排序,按顺序枚举,显然距离最远的点是单调的,线性时间可解出答案. 大包子的束缚 题目描 ...
- [八省联考2018]林克卡特树lct——WQS二分
[八省联考2018]林克卡特树lct 一看这种题就不是lct... 除了直径好拿分,别的都难做. 所以必须转化 突破口在于:连“0”边 对于k=0,我们求直径 k=1,对于(p,q)一定是从p出发,走 ...
- 【BZOJ5251】【八省联考2018】劈配(网络流,二分答案)
[BZOJ5251][八省联考2018]劈配(网络流,二分答案) 题面 洛谷 BZOJ Description 一年一度的综艺节目<中国新代码>又开始了. Zayid从小就梦想成为一名程序 ...
随机推荐
- FreeNAS:创建 CIFS 共享(权限)
第一部分:新建账户与指定数据集权限 简单起见,本教程主要介绍带基本身份验证的 CIFS 共享,即只有输入正确的用户名和密码才可以访问共享目录.关于创建匿名共享.多用户权限管理以及域控制器相关内容,我们 ...
- 分布式追踪系统sleauth+zipkin
- UML建工工具
本篇博文简单介绍一下自己在搜索UML建模工具的过程中收集到的一些信息. 如果想用中文的,可以考虑楚凡科技的Trufun Plato,不过最近好像没有怎么更新了. 很多前辈以前用的是Rational R ...
- SpringBoot系列: 使用 consul 作为服务注册组件
本文基本上摘自纯洁的微笑的博客 http://www.ityouknow.com/springcloud/2018/07/20/spring-cloud-consul.html . 感谢作者的付出. ...
- Windows系统盘符错乱导致桌面无法加载。
问题如下 : 同事有台笔记本更换SSD硬盘,IT职员帮他将新硬盘分好区后再将系统完整Ghost过来,然后装到笔记本上.理论上直接就可以使用了!但结果开机后登陆用户桌面无法显示,屏幕黑屏什么都没有. 问 ...
- Database学习 - mysql 视图/触发器/函数
- iTOP-4412开发板_驱动_adc驱动升级和测试例程
本文档介绍 iTOP-4412 开发板的 adc 驱动的升级和测试例程.自带的驱动只能支持一路 adc,本文介绍如何修改可以支持 4 路 adc 的控制.1 硬件简介如下图所示,这是 4412 的 d ...
- maven 分隔环境
在pom.xml 上 添加 把要分隔的环境 文件 弄成这样 打包 mvn clean package -Dmaven.test.skip=true -P+环境名 例子:mvn clean packag ...
- [Kubernetes]谈谈Kubernetes的本质
当下k8s算是比较火的一个内容,那么它到底是什么呢,它为什么会这么火呢,它解决的是什么问题呢.这篇文章就尝试着来讲讲,Kubernetes的本质. 当我们谈Kubernetes的时候,总是会想起来Do ...
- C#基础之Assembly
一直以来,我们都在用C#编写程序,编写程序的时候,我们用到继承.多态.接口以及泛型,我们也都明白子类可以继承抽象类,并能够重写父类的抽象方法,可是大家是否想过,如下几个问题: 1.凡树必有根和叶,类的 ...