【HDOJ3047】Zjnu Stadium(带权并查集)

题意:浙江省第十二届大学生运动会在浙江师范大学举行,为此在浙师大建造了一座能容纳近万人的新体育场。 
观众席每一行构成一个圆形,每个圆形由300个座位组成,对300个座位按照顺时针编号1到300,且可以认为有无数多行。现在比赛的组织者希望观众进入场地的顺序可以更加的有趣,在门票上并没有规定每个人的座位,而是与这个圈中某个人的相对位置,可以坐在任意一行。 
门票上标示的形式如下:A B x 表示第B个人必须在A的顺时针方向x个位置(比如A坐在4号位子,x=2,则B必须坐在6号位子)。 
现在你就座位志愿者在入场口检票。如果拿到一张门票,与之前给定的矛盾,则被视为是假票,如果无矛盾,视为真票。现在给定该行入场观众的顺序,以及他们手中的门票,请问其中有多少假票?

第一行两个数N(1<=N<=50,000)和m(1<=m<=100,000)。表示N个人,m张票。

思路:复习下带权并查集的模板

dis[x]代表路径压缩后到根结点的距离

合并集合时新的dis可以使用向量运算求出

 1 var f,dis:array[1..60000]of longint;
 2     n,m,i,u,v,x,y,z,ans:longint;
 3
 4 function find(k:longint):longint;
 5 var x:longint;
 6 begin
 7  if k=f[k] then exit(k);
 8  x:=f[k];
 9  f[k]:=find(f[k]);
10  dis[k]:=(dis[k]+dis[x]) mod 300;
11  exit(f[k]);
12 end;
13
14 procedure union(x,y,z:longint);
15 var u,v:longint;
16 begin
17  u:=find(x); v:=find(y);
18  f[v]:=u;
19  dis[v]:=(dis[x]+z-dis[y]+300) mod 300;
20 end;
21
22 begin
23  assign(input,‘hdoj3047.in‘); reset(input);
24  assign(output,‘hdoj3047.out‘); rewrite(output);
25  while not eof do
26  begin
27   readln(n,m);
28   if (n=0)and(m=0) then break;
29   ans:=0;
30   for i:=1 to n do
31   begin
32    f[i]:=i; dis[i]:=0;
33   end;
34   for i:=1 to m do
35   begin
36    readln(x,y,z);
37    u:=find(x); v:=find(y);
38    if u<>v then union(x,y,z)
39     else if (dis[x]+z) mod 300<>dis[y] then inc(ans);
40   end;
41   writeln(ans);
42  end;
43  close(input);
44  close(output);
45 end.
时间: 2024-10-15 05:35:22

【HDOJ3047】Zjnu Stadium(带权并查集)的相关文章

HDU 3047 Zjnu Stadium 带权并查集

题目来源:HDU 3047 Zjnu Stadium 题意:给你一些人 然后每次输入a b c 表示b在距离a的右边c处 求有多少个矛盾的情况 思路:用sum[a] 代表a点距离根的距离 每次合并时如果根一样 判断sum数组是否符合情况 根不一样 合并两棵树 这里就是带权并查集的精髓 sum[y] = sum[a]-sum[b]+x 这里y的没有合并前b的根 #include <cstdio> #include <cstring> using namespace std; cons

HDU3047 Zjnu Stadium 带权并查集

转:http://blog.csdn.net/shuangde800/article/details/7983965 #include <cstdio> #include <cstring> #include <queue> #include <set> #include <map> #include <stack> #include <cstdlib> #include <algorithm> #includ

hdu3047Zjnu Stadium 带权并查集

//n列个座位,排数为无穷 //m个询问 //a,b,x ,a在b前面x列 //问这m个询问与其前面询问冲突的有多少个 //带权并查集存下每个点到这个集合中最前的距离 #include<cstdio> #include<cstring> #include<iostream> using namespace std ; const int maxn = 50010 ; int F[maxn] ; int v[maxn] ; int n , m ; int find(int

【带权并查集】HDU 3047 Zjnu Stadium

http://acm.hdu.edu.cn/showproblem.php?pid=3047 [题意] http://blog.csdn.net/hj1107402232/article/details/9921311 [Accepted] 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<cmath> 6 #incl

并查集练习2(带权并查集)

明天旅游去爬山逛庙玩,今天练一天然后早早睡觉啦~ poj1703 Find them, Catch them (带权并查集) 1 #include<cstdio> 2 const int N=1e5+1; 3 int f[N]; 4 int r[N];//表示与父节点的关系,0同类,1不同类 5 int n; 6 void init(){ 7 for(int i=1;i<=n;++i){ 8 f[i]=i; r[i]=0; 9 } 10 } 11 int fin(int x){ 12 i

hdu3038(带权并查集)

题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=3038 题意: n表示有一个长度为n的数组, 接下来有m行形如x, y, d的输入, 表示从第x,个元素到第y个元素的和为d(包括x, 和y), 问m行输入里面有几个是错误的(第一个输入是正确的); 思路: 很显然带权并查集咯,我们可以用距离的概念代替和的概念比较好理解一点,d表示x到y的和即x到y的距离; 可以用rank[x]表示x到其父亲节点的距离,  将正确的距离关系合并到并查集中

【POJ1182】 食物链 (带权并查集)

Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有人用两种说法对这N个动物所构成的食物链关系进行描述: 第一种说法是"1 X Y",表示X和Y是同类. 第二种说法是"2 X Y",表示X吃Y. 此人对N个动物,用上述两种说法,一句接一句地说出K句话,这K句话有的是真的,有的是假的.当一句话满足下列三条之

【poj 1988】Cube Stacking(图论--带权并查集 模版题)

题意:有N个方块,M个操作{“C x”:查询方块x上的方块数:“M x y”:移动方块x所在的整个方块堆到方块y所在的整个方块堆之上}.输出相应的答案. 解法:带权并查集.每堆方块作为一个集合,维护3个数组:fa[x]表示x方块所在堆的最顶部的方块:d[x]表示x方块所在堆的最底部的方块:f[x]表示x方块方块x上的方块数. 1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<

Lightoj1009 Back to Underworld(带权并查集)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Back to Underworld Time Limit:4000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Description The Vampires and Lykans are fighting each other to death. The war has become so fierc