1. 程式人生 > >親戚 並查集經典題目

親戚 並查集經典題目

親戚

題目描述
       或許你並不知道,你的某個朋友是你的親戚。他可能是你的曾祖父的外公的女婿的外甥女的表姐的孫子。如果能得到完整的家譜,判斷兩個人是否親戚應該是可行的,但如果兩個人的最近公共祖先與他們相隔好幾代,使得家譜十分龐大,那麼檢驗親戚關係實非人力所能及。在這種情況下,最好的幫手就是計算機。為了將問題簡化,你將得到一些親戚關係的資訊,如 Marry 和Tom 是親戚,Tom 和 Ben 是親戚,等等。從這些資訊中,你可以推出 Marry 和 Ben 是親戚。請寫一個程式,對於我們的關於親戚關係的提問,以最快的速度給出答案。

輸入格式
       輸入由兩部分組成。第一部分以 N,M 開始。N 為問題涉及的人的個數(1≤N≤20000)。這些人的編號為 1,2,3,…, N。下面有 M 行(1≤M≤1000000),每行有兩個數 ai, bi,表示已知 ai 和 bi 是親戚。
第二部分以 Q 開始。以下 Q 行有 Q 個詢問(1≤Q≤1000000),每行為 ci, di,表示詢問 ci 和 di 是否為親戚。

輸出格式
       對於每個詢問 ci, di,輸出一行:若 ci 和 di 為親戚,則輸出“Yes”,否則輸出“No”。

樣例資料 1
輸入

10 7 
2 4 
5 7 
1 3 
8 9 
1 2 
5 6 
2 3 

3 4 
7 10 
8 9
輸出

Yes 
No 
Yes

分析:       這道題是並查集的模板題,沒什麼需要多說的。只需要注意一下資料規模。由於資料太多,常規輸入輸出過不完所有資料,所以必須使用讀入優化代替 scanf() 函式,輸出用 cout 代替 printf。  下面是程式碼:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <cctype>
#include <ctime>
#include <queue>
using namespace std;

int n,m,i,j;
int father[20001];

int get_int()
{
   int x=0;
   char ch;
   for(ch=getchar();ch<'0'||ch>'9';ch=getchar());
   for(;ch>='0'&&ch<='9';ch=getchar())
     x=(x<<3)+(x<<1)+ch-'0';
   return x;
}

int getfather(int v)
{
   if(father[v]==v) return v;
   father[v]=getfather(father[v]);
   return father[v];
}

void merge(int x,int y)
{
   int i,j;
   i=getfather(x);
   j=getfather(y);
   if(father[i]!=father[j]) father[i]=j;
}

int main()
{
   freopen("lx.in","r",stdin);
   freopen("lx.out","w",stdout);
   int x,y;
   memset(father,0,sizeof(father));

   n=get_int();
   m=get_int();

   for(int i=1;i<=n;i++) father[i]=i;
   for(int i=1;i<=m;i++)
   {
   	 x=get_int();
   	 y=get_int();
   	 merge(x,y);
   }

   int q;
   q=get_int();
   for(int i=1;i<=q;i++)
   {
   	 x=get_int();
   	 y=get_int();
   	 if(getfather(x)==getfather(y)) cout<<"Yes"<<endl;
   	 else cout<<"No"<<endl;
   }

   return 0;
}

讀入優化在比賽中是必打的,因為可以有效節約執行時間,防止超時,所以建議記住。

相關推薦

親戚 經典題目

親戚 題目描述        或許你並不知道,你的某個朋友是你的親戚。他可能是你的曾祖父的外公的女婿的外甥女的表姐的孫子。如果能得到完整的家譜,判斷兩個人是否親戚應該是可行的,但如果兩個人的最近公共祖

經典題目

還是先看兩道題: 試題描述 俗話說得好,敵人的敵人就是朋友。現在有n個人,編號1至n,初始互不相識。接下來有m個操作,操作分為兩種: (1)檢查x號和y號是否是朋友,若不是,則變成敵人 (2)詢問x號的朋友有多少個 請你針對每個操作中的詢問給出回答。 輸入

洛谷P1551親戚

con ++ i++ void amp using blog print 壓縮 洛谷P1551親戚 並查集 按秩合並 + 路徑壓縮 #include <bits/stdc++.h> using namespace std ; const int

【codevs1073/P1551】家族/親戚——

sin name 分享 char 找到 play www. i++ pan 題目鏈接:codevs,洛谷 這道題就是並查集的基礎題,getf函數尋找該節點的祖先,要註意在查找的時候可以順便把路上的節點的父節點也改為當前祖先(即路徑壓縮)。 詢問的時候不能因為兩

luogu P1551 親戚(入門)

這是一個並查集模板。    說一下並查集,雖然我也是剛剛學會沒幾天。。。 並查集是個樹形結構的資料結構,主要用於合併兩個不相交的集合; 首先是初始化,其中的f陣列表示第i點的父親 for(int i=1;i<=n;i++)f[i] = i;  並查集分為合併與

POJ 1182 食物鏈 帶權經典

食物鏈 動物王國中有三類動物A,B,C,這三類動物的食物鏈構成了有趣的環形。A吃B, B吃C,C吃A。  現有N個動物,以1-N編號。每個動物都是A,B,C中的一種,但是我們並不知道它到底是哪一種。 有人用兩種說法對這N個動物所構成的食物鏈關係進行描述:  第一種說法是"1

POJ 1182 食物鏈 帶權經典

食物鏈 動物王國中有三類動物A,B,C,這三類動物的食物鏈構成了有趣的環形。A吃B, B吃C,C吃A。  現有N個動物,以1-N編號。每個動物都是A,B,C中的一種,但是我們並不知道它到底是哪一種。 有人用兩種說法對這N個動物所構成的食物鏈關係進行描述:  第一種說法是"1

【洛谷】P1551 親戚

連結:https://www.luogu.org/problemnew/show/P1551 import java.util.Scanner; public class Main{ public static void main(String[] args) {

1182 食物鏈 經典

          思路:設r(x)表示節點x與根結點的關係,px表示x的根結點。記錄每個節點與其父節點的關係,就能很方便知道每個節點以及和它的父節點的關係。 struct node{ int pa

複習+Leetcode下相關題目

目錄 題目: 解析: 一、並查集介紹及其模板 1、並查集介紹 並查集又名不相交集合,實質上是父指標表示法的一般樹,每個節點都有指向其父親的指標(根節點除外),通常用一維陣列實現。並查集最常見的操作有兩種,一是union(x, y),表示將x節

TOJ 2469.Friends(基礎題目

There are some people traveling together. Some of them are friends. The friend relation is transitive, that is, if A and B are friends, B and C are friend

POJ3728The merchant (倍增)(LCA)(DP)(經典)(||壓縮路徑?)

城市 contain 分析 之間 pat rst .com span 題解 There are N cities in a country, and there is one and only one simple path between each pair of c

圖論題目模板,和:以後的圖論題目就靠他了

fat union 一次 情況 返回 end empty 是我 min ‘‘‘ 並查集: 1.用於查如何A,B是否在一個集合中. 2.每一個集合設立一個頭結點.其他都連向他 3.集合合並就是把小的集合掛到大的集合下面即可 4.優化.查詢到一個a在b這個頭結點下面,那麽直

HDU 1811 Rank of Tetris(+拓撲排序 非常經典

memory max scan ble tput col turn 排行榜 行動 Rank of Tetris Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe

帶權經典-食物鏈,poj-1182

                        &n

Virtual Friends 【HDU - 3172】【帶權】【題目不難、但有坑點】

題目連結   為什麼能這麼埋坑???我還以為我錯了,結果找不到BUG,後來一看Discuss,發現竟是這種問題。。。   一般情況,我們都是while(T--)就行,但這道題可真就不一樣了,它還需要while(scanf("%d", &T)!=EOF)!

POJ 1182 ——食物鏈 經典

題意 :有A,B,C三種動物構成環形的食物鏈,現給你M句話,每句話形式"D X Y",1表示X和Y同類,2表示X吃Y。判斷假話有多少句。其中 :1)與前面的話衝突 2)X和Y大於動物編號N 3)D =2 &&X =Y 是假話。 思路 :這是一

POJ食物鏈(經典種類

食物鏈 動物王國中有三類動物A,B,C,這三類動物的食物鏈構成了有趣的環形。A吃B, B吃C,C吃A。  現有N個動物,以1-N編號。每個動物都是A,B,C中的一種,但是我們並不知道它到底是哪一種。  有人用兩種說法對這N個動物所構成的食物鏈關係進行描述:  第一種

洛谷P1141 01迷宮 經典 Dfs + 記憶化搜尋,

將方向用自定義陣列迴圈化 ,讀入時注意字串處理,走過的地方記憶化。並查集,不同聯通塊採用不同顏色標記記憶,方便多次查詢。並記憶每種顏色染色數量(即聯通塊大小)。 #include<cstdio&

3172】【帶權】【題目不難、但有坑點】

題目連結   為什麼能這麼埋坑???我還以為我錯了,結果找不到BUG,後來一看Discuss,發現竟是這種問題。。。   一般情況,我們都是while(T--)就行,但這道題可真就不一樣了,它還需要while(scanf("%d", &T)!=EOF)!!!