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从小就梦想成为一名程序 ...
随机推荐
-
JavaScript工具代码
html编码 function htmlEscape(sHtml){ return sHtml && sHtml.replace(/[<>&"]/g, f ...
-
linux下vim命令详解 转自: zhanglong0426
高级一些的编辑器,都会包含宏功能,vim当然不能缺少了,在vim中使用宏是非常方便的: :qx 开始记录宏,并将结果存入寄存器xq 退出记录模式@x 播放记录在x寄存器中的 ...
-
【BZOJ】【2038】小Z的袜子
填个坑吧,学习了莫队算法.我也忘记是看的哪位大牛的博客&代码学习的了T_T,如果您发现了的话请私信我,我会注明学自您的代码. 另外感谢@PoPoQQQ大神 好,进入正文,莫队算法,也算是一种暴 ...
-
JavaScript面向对象,闭包内存图,闭包和作用域
var i = 10; function test(){ var j; i=20; //未定义 function test(){ j='hello'; } console.log(test()); / ...
-
树的判断(poj nyoj hduoj)
题目: http://ac.jobdu.com/problem.php?pid=1481 http://acm.nyist.net/JudgeOnline/problem.php?pid=129 ht ...
-
Android OpenGL 入门示例----绘制三角形和正方形
Android上对OpenGl的支持是无缝的,所以才有众多3D效果如此逼真的游戏,在Camera的一些流程中也有用到GLSurfaceView的情况.本文记录OpenGL在Android上的入门级示例 ...
-
SwipeRefreshLayout实现上拉下拉刷新
1:在布局中添加SwipeRefreshLayout和Listview组件 [html] view plain copy <?xml version="1.0" encodi ...
-
Aerospike系列:3:aerospike特点分析
1. 数据存放 数据可以放内存,也可以放SSD. 数据放内存时速度肯定会很快,但这和memcache一样,相比memcache性能并没有优势 数据放内存时可以进行持久化配置,但文档只有一个地方提了 ...
-
021.8 properties(开发使用频率高)
内容:Properties基本存取.存储到持久化设备.从持久化设备读取.简单模拟收费软件试用结束##Properties——有配置文件的功能. 特点: 1.Hash table的子类,ma ...
-
Android开发中dp、dpi、px的区别(转)
一.基本概念 - dp:安卓中的相对大小 - dpi:(dot per inch)每英寸像素多少 - px:像素点 二.详细说明 1.px和dpi - px: 平常所说的1920×1080只是像素数量 ...