• P1196 [NOI2002]银河英雄传说 【带权并查集】


     

     

     思路

      用sum记录每个舰队的战舰数量, tohead 记录当前舰离舰首的距离,那么求任意两舰之间有多少舰显然就是 abs( tohead[i] - tohead[j] ) - 1;

    CODE

     1 #include <bits/stdc++.h>
     2 #define dbg(x) cout << #x << "=" << x << endl
     3 #define eps 1e-8
     4 #define pi acos(-1.0)
     5 
     6 using namespace std;
     7 typedef long long LL;
     8 
     9 template<class T>inline void read(T &res)
    10 {
    11     char c;T flag=1;
    12     while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
    13     while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
    14 }
    15 
    16 namespace _buff {
    17     const size_t BUFF = 1 << 19;
    18     char ibuf[BUFF], *ib = ibuf, *ie = ibuf;
    19     char getc() {
    20         if (ib == ie) {
    21             ib = ibuf;
    22             ie = ibuf + fread(ibuf, 1, BUFF, stdin);
    23         }
    24         return ib == ie ? -1 : *ib++;
    25     }
    26 }
    27 
    28 int qread() {
    29     using namespace _buff;
    30     int ret = 0;
    31     bool pos = true;
    32     char c = getc();
    33     for (; (c < '0' || c > '9') && c != '-'; c = getc()) {
    34         assert(~c);
    35     }
    36     if (c == '-') {
    37         pos = false;
    38         c = getc();
    39     }
    40     for (; c >= '0' && c <= '9'; c = getc()) {
    41         ret = (ret << 3) + (ret << 1) + (c ^ 48);
    42     }
    43     return pos ? ret : -ret;
    44 }
    45 
    46 const int maxn = 5e4 + 7;
    47 
    48 int fa[maxn];
    49 int tohead[maxn], sum[maxn];
    50 int t;
    51 
    52 int fid(int x) {
    53     if(fa[x] == x) {
    54         return x;
    55     }
    56     int r1 = fa[x], r2 = fid(fa[x]);
    57     fa[x] = r2;
    58     tohead[x] += tohead[r1];
    59     return r2;
    60 }
    61 
    62 void join(int x, int y) {
    63     int fx = fid(x), fy = fid(y);
    64     fa[fy] = fx;
    65     tohead[fy] = sum[fx];
    66     sum[fx] += sum[fy];
    67     sum[fy] = 0;
    68 }
    69 
    70 int main()
    71 {
    72     scanf("%d",&t);
    73     for ( int i = 1; i <= 30007; ++i ) {
    74         fa[i] = i;
    75         sum[i] = 1;
    76     }
    77     while(t--) {
    78         char s[5];
    79         int x, y;
    80         cin >> s;
    81         scanf("%d %d",&x, &y);
    82         if(s[0] == 'M') {
    83             join(x, y);
    84         }
    85         else {
    86             if(fid(x) != fid(y)) {
    87                 printf("-1
    ");
    88                 continue;
    89             }
    90             else {
    91                 printf("%d
    ",abs(tohead[x] - tohead[y]) - 1);
    92             }
    93         }
    94     }
    95     return 0;
    96 }
    View Code
  • 相关阅读:
    关于类加载
    Java垃圾回收机制复习
    关于网络协议
    hadoop
    dubbo框架原理
    经典场景的设计方案整理
    报告撰写,linux使用gimp简单做gif动图
    《Linux命令行与shell脚本编程大全 第3版》创建实用的脚本---11
    《Linux命令行与shell脚本编程大全 第3版》创建实用的脚本---10
    《Linux命令行与shell脚本编程大全 第3版》创建实用的脚本---07
  • 原文地址:https://www.cnblogs.com/orangeko/p/12376627.html
Copyright © 2020-2023  润新知