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('\n'); 90 } 91 } 92 } 93 94 int main(){ 95 // file(); 96 read(t); 97 for(int i = 1;i <= t; ++ i){ 98 printf("Case %d:\n",i); 99 work(); 100 } 101 return 0; 102 }
非做顽石不可,哪管他敬仰暗唾