zoukankan      html  css  js  c++  java
  • 【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.

     UPD(2018.10.18):C++

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<string>
     4 #include<cmath>
     5 #include<iostream>
     6 #include<algorithm>
     7 #include<map>
     8 #include<set>
     9 #include<queue>
    10 #include<vector>
    11 using namespace std;
    12 typedef long long ll;
    13 typedef unsigned int uint;
    14 typedef unsigned long long ull;
    15 typedef pair<int,int> PII;
    16 typedef vector<int> VI;
    17 #define fi first
    18 #define se second
    19 #define MP make_pair
    20 #define N   61000
    21 #define M   6100000
    22 #define eps 1e-8
    23 #define pi  acos(-1)
    24 #define oo  1e9
    25 
    26 int f[N],dis[N];
    27 
    28 int find(int k)
    29 {
    30     if(k==f[k]) return k;
    31     int x=f[k];
    32     f[k]=find(f[k]);
    33     dis[k]=(dis[k]+dis[x])%300;
    34     return f[k];
    35 }
    36 
    37 void Union(int x,int y,int z)
    38 {
    39     int u=find(x);
    40     int v=find(y);
    41     f[v]=u;
    42     dis[v]=(dis[x]+z-dis[y]+300)%300;
    43 }
    44 
    45 int main()
    46 {
    47     //freopen("hdoj3047.in","r",stdin);
    48     //freopen("hdoj3047.out","w",stdout);
    49     int n,m;
    50     while(scanf("%d%d",&n,&m)!=EOF)
    51     {
    52         int ans=0;
    53         memset(dis,0,sizeof(dis));
    54         for(int i=1;i<=n;i++) f[i]=i;
    55         for(int i=1;i<=m;i++)
    56         {
    57             int x,y,z;
    58             scanf("%d%d%d",&x,&y,&z);
    59             int u=find(x);
    60             int v=find(y);
    61             if(u!=v) Union(x,y,z);
    62              else if((dis[x]+z)%300!=dis[y]) ans++;
    63         }
    64         printf("%d
    ",ans);
    65     }    
    66     return 0;
    67 }
  • 相关阅读:
    BestCoder6 1002 Goffi and Squary Partition(hdu 4982) 解题报告
    codeforces 31C Schedule 解题报告
    codeforces 462C Appleman and Toastman 解题报告
    codeforces 460C. Present 解题报告
    BestCoder3 1002 BestCoder Sequence(hdu 4908) 解题报告
    BestCoder3 1001 Task schedule(hdu 4907) 解题报告
    poj 1195 Mobile phones 解题报告
    二维树状数组 探索进行中
    codeforces 460B Little Dima and Equation 解题报告
    通过Sql语句控制SQLite数据库增删改查
  • 原文地址:https://www.cnblogs.com/myx12345/p/7384144.html
Copyright © 2011-2022 走看看