CHOJ 4101 銀河英雄傳說【邊帶權並查集】
描述
公元五八○一年,地球居民遷移至金牛座α第二行星,在那裡發表銀河聯邦創立宣言,同年改元為宇宙曆元年,並開始向銀河系深處擴充。
宇宙歷七九九年,銀河系的兩大軍事集團在巴米利恩星域爆發戰爭。泰山壓頂集團派宇宙艦隊司令萊因哈特率領十萬餘艘戰艦出征,氣吞山河集團點名將楊威利組織麾下三萬艘戰艦迎敵。
楊威利擅長排兵佈陣,巧妙運用各種戰術屢次以少勝多,難免恣生驕氣。在這次決戰中,他將巴米利恩星域戰場劃分成30000列,每列依次編號為1, 2, …, 30000。之後,他把自己的戰艦也依次編號為1, 2, …, 30000,讓第i號戰艦處於第i列(i = 1, 2, …, 30000),形成“一字長蛇陣”,誘敵深入。這是初始陣形。當進犯之敵到達時,楊威利會多次釋出合併指令,將大部分戰艦集中在某幾列上,實施密集攻擊。合併指令為M i j,含義為讓第i號戰艦所在的整個戰艦佇列,作為一個整體(頭在前尾在後)接至第j號戰艦所在的戰艦佇列的尾部。顯然戰艦佇列是由處於同一列的一個或多個戰艦組成的。合併指令的執行結果會使佇列增大。
然而,老謀深算的萊因哈特早已在戰略上取得了主動。在交戰中,他可以通過龐大的情報網路隨時監聽楊威利的艦隊調動指令。
在楊威利釋出指令調動艦隊的同時,萊因哈特為了及時瞭解當前楊威利的戰艦分佈情況,也會發出一些詢問指令:C i j。該指令意思是,詢問電腦,楊威利的第i號戰艦與第j號戰艦當前是否在同一列中,如果在同一列中,那麼它們之間佈置有多少戰艦。
作為一個資深的高階程式設計員,你被要求編寫程式分析楊威利的指令,以及回答萊因哈特的詢問。
最終的決戰已經展開,銀河的歷史又翻過了一頁……
輸入格式
第一行有一個整數T(1 <= T <= 500,000),表示總共有T條指令。
以下有T行,每行有一條指令。指令有兩種格式:
1. M i j :i和j是兩個整數(1 <= i , j <= 30000),表示指令涉及的戰艦編號。該指令是萊因哈特竊聽到的楊威利釋出的艦隊調動指令,並且保證第i號戰艦與第j號戰艦不在同一列。
2. C i j :i和j是兩個整數(1 <= i , j <= 30000),表示指令涉及的戰艦編號。該指令是萊因哈特釋出的詢問指令。
輸出格式
你的程式應當依次對輸入的每一條指令進行分析和處理:
如果是楊威利釋出的艦隊調動指令,則表示艦隊排列發生了變化,你的程式要注意到這一點,但是不要輸出任何資訊;
如果是萊因哈特釋出的詢問指令,你的程式要輸出一行,僅包含一個整數,表示在同一列上,第i號戰艦與第j號戰艦之間佈置的戰艦數目。如果第i號戰艦與第j號戰艦當前不在同一列上,則輸出-1。
樣例輸入
4 M 2 3 C 1 2 M 2 4 C 4 2
樣例輸出
-1 1
題解:並查集的實質是由若干棵樹構成的森林。一條鏈也是一棵樹,只不過是樹的特殊形態。把每一列戰艦看作一個集合,用並查集維護。最初, N個戰艦構成N個獨立的集合。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 30000+7;
int fa[maxn];
int d[maxn], Size[maxn];// d[x] 表示 x 到父節點 fa[x] 之間的邊權, Size[x]表示集合x的大小
int get(int x) {
if(x == fa[x]) return x;
int rt = get(fa[x]);//遞迴計算集合代表
d[x] += d[fa[x]];//維護d陣列,對邊權求和
return fa[x] = rt;//路徑壓縮
}
void Merge(int x, int y) {
x = get(x), y = get(y);
fa[x] = y, d[x] = Size[y];//合併之後x到根節點之間的邊權就是集合 y 的大小
Size[y] += Size[x];
}
int main()
{
int t, a, b;
char cd[2];
for(int i = 1; i <= maxn; i++)
fa[i] = i, Size[i] = 1;
memset(d, 0, sizeof d);
scanf("%d", &t);
while(t--) {
scanf("%s %d %d", &cd[0], &a, &b);
if(cd[0] == 'M'){
Merge(a, b);
}else{
if(get(a) == get(b)){
printf("%d\n", abs(d[a]-d[b])-1);
}else printf("-1\n");
}
}
return 0;
}
相關文章
- 銀河英雄傳說(並查集)並查集
- 銀河英雄傳說
- 並查集到帶權並查集並查集
- P1196 [NOI2002] 銀河英雄傳說
- 洛谷 P1196 [NOI2002] 銀河英雄傳說
- POJ 1182 食物鏈【擴充套件域 | 邊帶權並查集】套件並查集
- POJ 2492 A bug's life【擴充套件域 | 邊帶權並查集】套件並查集
- 樹(tree) - 題解(帶權並查集)並查集
- 【資料結構】帶權並查集資料結構並查集
- 【帶權並查集】理論和應用並查集
- bzoj4690: Never Wait for Weights(帶權並查集)AI並查集
- 三體之後銀河紀元傳說
- 【並查集】【帶偏移的並查集】食物鏈並查集
- 關押罪犯 擴充套件域並查集 帶權並查集 二分圖+二分套件並查集
- Luogu1196 銀河英雄傳說 + Python函式的定義與呼叫(C++/Python 雙語言實現)Python函式C++
- 查並集
- 並查集(一)並查集的幾種實現並查集
- 並查集(小白)並查集
- [leetcode] 並查集(Ⅱ)LeetCode並查集
- [leetcode] 並查集(Ⅲ)LeetCode並查集
- [leetcode] 並查集(Ⅰ)LeetCode並查集
- 3.1並查集並查集
- [kuangbin帶你飛]專題五 並查集 題解並查集
- 並查集應用並查集
- 寫模板, 並查集。並查集
- 並查集的使用並查集
- 並查集跳躍並查集
- 各種並查集並查集
- 淺談並查集並查集
- 食物鏈(並查集)並查集
- 並查集(Union Find)並查集
- The Door Problem 並查集並查集
- 並查集練習並查集
- 並查集(二)並查集的演算法應用案例上並查集演算法
- 《公理邊緣 2》Polygon 評測:「銀河戰士」的忠實信徒Go
- 從玩家角度解析為什麼《星球大戰:銀河英雄》這麼耐玩
- 並查集題目合集並查集
- 並查集深度應用並查集