zoukankan      html  css  js  c++  java
  • HDU 3635 Dragon Balls [并查集]

    题意:有n颗龙珠分别顺序放在n个城市中,有两种操作

      (1)T A B:把A所在城市的所有龙珠转运到B所在的城市。

      (2)Q A :查询A所在的城市,所在城市的龙珠个数,A被转运了几次

    思路:开始就是想用并查集做,但是处理细节很麻烦,每个节点记录被转运的次数,路径压缩时就可以修改节点,别的方法没想到...输入数据很多cin回超时。

    #include <iostream>
    #include
    <cstdio>
    #include
    <algorithm>
    #include
    <memory.h>
    #include
    <cmath>
    #include
    <bitset>
    #include
    <queue>
    #include
    <vector>
    #include
    <map>
    #include
    <stack>
    #include
    <set>
    #include
    <list>
    #include
    <deque>
    #include
    <cstdlib>
    #include
    <cstring>
    const int BORDER = (1<<20)-1;
    const int MAXSIZE = 37;
    const int MAXN = 20500;
    const int INF = 0x3f3f3f3f;

    #define CLR(x,y) memset(x,y,sizeof(x))
    #define MIN(m,v) (m)<(v)?(m):(v)
    #define MAX(m,v) (m)>(v)?(m):(v)
    #define ABS(x) ((x)>0?(x):-(x))
    #define REP(i,x,y) for(i=x;i<y;++i)

    #define getbit(a,i) (a&(1<<i))
    #define setbit(a,i) (a|(1<<i))

    using namespace std;

    int pre[MAXN],ct[MAXN],num[MAXN];
    int ic,n,m;

    int find_set(int x)
    {
    int root = x;
    int tmp,tmp_c,t;
    t
    = 0;
    while(pre[root]>=0)
    {
    root
    = pre[root];
    t
    = t + ct[root];
    }
    ct[x]
    += t;
    while(x!=root)
    {
    tmp
    = pre[x];
    tmp_c
    = ct[tmp];
    pre[x]
    = root;
    ct[tmp]
    = t;
    t
    -= tmp_c;
    x
    = tmp;
    }
    return root;
    }
    void union_set(const int& root1,const int& root2)
    {
    if(num[root1] == 0)
    return ;
    num[root2]
    += num[root1];
    num[root1]
    = 0;
    ++ct[root1];
    pre[root2]
    += pre[root1];
    pre[root1]
    = root2;
    return ;
    }

    int init()
    {
    CLR(ct,
    0);
    CLR(pre,
    -1);
    return 0;
    }
    int input()
    {
    scanf(
    "%d%d",&n,&m);
    int i;
    REP(i,
    0,n+1)
    num[i]
    = 1;
    return 0;
    }
    int work()
    {
    int i,a,b;
    int pos,cnt,t;
    int root1,root2;
    char ch[3];
    printf(
    "Case %d:\n",ic);
    ++ic;
    REP(i,
    0,m)
    {
    scanf(
    "%s",ch);
    if(ch[0] == 'T')
    {
    scanf(
    "%d %d",&a,&b);
    root1
    = find_set(a);
    root2
    = find_set(b);
    union_set(root1,root2);
    }
    else
    {
    scanf(
    "%d",&a);
    pos
    = find_set(a);
    printf(
    "%d %d %d\n",pos,num[pos],ct[a]);
    }
    }
    return 0;
    }
    int main()
    {
    ic
    = 1;
    int tt;
    scanf(
    "%d",&tt);
    while(tt--)
    {
    init();
    input();
    work();
    }
    return 0;
    }

  • 相关阅读:
    Response/Request
    每日总结-Day5
    每日总结-Day4
    每日总结-Day3
    每日总结-Day2
    每日总结-Day1
    day6
    Day5
    Day4
    需求分析之软件初设想
  • 原文地址:https://www.cnblogs.com/lvpengms/p/1832936.html
Copyright © 2011-2022 走看看