[codevs1540]银河英雄传说
来源:互联网 发布:linux 线程默认优先级 编辑:程序博客网 时间:2024/04/28 02:51
“我们的征途是星辰大海”
银英传←
这才是题目←
思路:
加权并查集
维护f[i],t[i],cnt[i]
cnt[i]->i在当前队列中后面有多少元素
f[i]->i所在集合标志元素(队列底元素)
注意在未执行find(i)操作时,f[i]不一定为i真正的底
t[i]->i所在队列顶元素
t[i]仅在merge更新不再是队底的元素的cnt值时有意义
需要保证每个元素的f[i]的t、cnt等值时刻为实际值,这样每个元素在find后,t、cnt等可更新为实际值
有点像线段树的lazy思想?
/*4M 2 3C 1 2M 2 4C 4 2*/#include<iostream>#include<cstdio>#include<algorithm>using namespace std;const int MAXN = 200000 + 50;int f[MAXN],t[MAXN],cnt[MAXN];void init(int n){ for(int i = 1;i <= n;i ++) f[i] = i,t[i] = i;}int n;int find(int x){ if(x == f[x])return x; int fa = f[x]; f[x] = find(f[x]); cnt[x] += cnt[fa]; return f[x];}void merge(int a,int b){ a = find(a);b = find(b); find(t[b]);//t[b]不为标志元素,其值不一定为实际值 cnt[a] = cnt[t[b]] + 1; f[a] = b; t[b] = t[a];}char ch;int x,y;int main(){ cin >> n; init(30000); for(int i = 1;i <= n;i ++) { cin >> ch >> x >> y; if(ch == 'M') { merge(x,y); } else { find(x);find(y); if(f[x] != f[y]) { cout << -1 << '\n'; } else { if(cnt[x] < cnt[y])swap(x,y); cout << cnt[x] - cnt[y] - 1 << '\n'; } } }}
好像18年要重新动画化?emmmmm
阅读全文
0 0
- 【codevs1540】 银河英雄传说
- [codevs1540]银河英雄传说
- Codevs1540银河英雄传说
- 【CodeVS1540】【Vijos1443】【NOI2002】银河英雄传说
- codevs1540 银河英雄传说(NOI 2002)
- 【codevs1540】银河英雄传说,以前屯着没做的并查集
- TYVJ 银河英雄传说
- 【noi2002】银河英雄传说
- Noi2002银河英雄传说
- 【NOI2002】银河英雄传说
- 银河英雄传说
- 【u010】银河英雄传说
- 1540 银河英雄传说
- P1196 银河英雄传说
- [P1196]银河英雄传说
- 银河英雄传说
- NOI2002 银河英雄传说
- NOI2002 银河英雄传说
- EasyUI datagrid 左侧行号出现错位
- laravel框架搭建
- 线程方法
- 禁止html在手机端自由缩放
- Android开发学习——android与服务器端数据交互
- [codevs1540]银河英雄传说
- 03:不高兴的津津
- Android NV21 byte[] 数据转化为JPEG byte[] 数据
- Zookeeper初步了解
- sdnu1008
- 1048. Find Coins (25)
- JavaScript:On The Way...(1)JS基础:数据类型,操作符
- 字符串算法——查找数组第K个最大值( Kth Largest Element in an Array)
- 全卷积网络FCN详解