MZOJ #80 Hzwer的陨石

分析

有没有很像银河英雄传说?

好吧没有

问题不一样,不过换汤不换药

先看问题:在当前这个时候,i号陨石在所在区域x、x区域共有的陨石数y、以及i号陨石被搬运的次数z。

 这个,在并查集的merge与find中维护就好,相当于变相的树形DP啦

注意这一句:

首先,必需在father更新完后在更新儿子

但先不要更新father值

主要是trans(移动次数的更新),保证father不是根时才更新,避免重复加

代码

  1 /***********************
  2 User:Mandy.H.Y
  3 Language:c++
  4 Problem:MZOJ #80 Hzwer
  5 Algorithm:
  6 ***********************/
  7 //银河英雄传说?? 
  8 #include<bits/stdc++.h>
  9 
 10 using namespace std;
 11 
 12 const int maxn = 1e4 + 5;
 13 
 14 int t;
 15 int n,q;
 16 int father[maxn];
 17 int trans[maxn];
 18 int cnt[maxn],pos[maxn];
 19 
 20 template<class T>inline void read(T &x){
 21     x = 0;bool flag = 0;char ch = getchar();
 22     while(!isdigit(ch)) flag |= ch == '-',ch = getchar();
 23     while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48),ch = getchar();
 24     if(flag) x = -x;
 25 }
 26 
 27 template<class T>void putch(const T x){
 28     if(x > 9) putch(x / 10);
 29     putchar(x % 10 | 48);
 30 }
 31 
 32 template<class T>void put(const T x){
 33     if(x < 0) putchar('-'),putch(-x);
 34     else putch(x);
 35 }
 36 
 37 void file(){
 38     freopen("80.in","r",stdin);
 39 //    freopen("80.out","w",stdout);
 40 }
 41 
 42 void init(){
 43     for(int i = 1;i <= n; ++ i){
 44         father[i] = i;pos[i] = i;
 45         cnt[i] = 1;
 46     }
 47     memset(trans,0,sizeof(trans));
 48 }
 49 
 50 int find(int x){
 51     if(father[x] == x) return x;
 52     else {
 53         int fx = find(father[x]);
 54         if(father[father[x]] != father[x]) 
 55             trans[x] += trans[father[x]];
 56         father[x] = fx;
 57         pos[x] = pos[father[x]];
 58         return father[x];
 59     }
 60 }
 61 
 62 void merge(int x,int y){
 63     int fx = find(x),fy = find(y);
 64     father[fx] = fy;
 65     cnt[fy] += cnt[fx];
 66     cnt[fx] = 0;pos[fx] = pos[fy];
 67     trans[fx] ++;
 68 }
 69 
 70 void work(){
 71     read(n);read(q);
 72     init();
 73     for(int i = 1;i <= q; ++ i){ 
 74         char c = getchar();
 75         while(c != 'T' && c != 'Q') c = getchar();
 76         if(c == 'T'){
 77             int x,y;
 78             read(x);read(y);
 79             merge(x,y);
 80         } else {
 81             int j;
 82             read(j);
 83             int fx = find(j);
 84             int x = pos[fx];
 85             int y = cnt[fx];
 86             int z = trans[j];
 87             put(x);putchar(' ');
 88             put(y);putchar(' ');
 89             put(z);putchar('
');
 90         }
 91     }
 92 }
 93 
 94 int main(){
 95 //    file();
 96     read(t);
 97     for(int i = 1;i <= t; ++ i){
 98         printf("Case %d:
",i);
 99         work();
100     }
101     return 0;
102 }
View Code
非做顽石不可,哪管他敬仰暗唾
原文地址:https://www.cnblogs.com/Mandy-H-Y/p/11454938.html