犯罪團伙(並查集)
題目描述:
快過年了,犯罪分子們也開始為年終獎"奮鬥"作案了。小哼的家鄉出現了多次搶劫事件。由於強盜人數過於龐大。作案頻繁,警方想查清楚到底有幾個犯罪團伙實在太不容易了,不過警察叔叔還是蒐集到了一些證據,需要咱們幫忙分析一下:
例:
現在有10個強盜
1號強盜與2號強盜是同夥
3號強盜與4號強盜是同夥
5號強盜與2號強盜是同夥
4號強盜與6號強盜是同夥
2號強盜與6號強盜是同夥
8號強盜與7號強盜是同夥
9號強盜與7號強盜是同夥
1號強盜與6號強盜是同夥
2號強盜與4號強盜是同夥
有一點要注意:強盜的同夥也是同夥。你能幫警方查出有多少獨立的犯罪團伙嗎?
思路:
首先我們假設這10個強盜相互是不認識的,他們各自為政,每個人都是首領,他們只聽從自己的。
之後我們將通過警方提供的線索,一步步來"合併同夥"
程式碼:
#include<stdio.h> int f[1000]={0}; int n,m,k,sum; //這裡是初始化,數組裡存的是自己陣列下標的編號 void init() { for(int i=1;i<=n;i++) f[i]=i; } //這是找爹的遞迴函式,不停地去找爹,直到找到祖宗為止,其實就是去找犯罪團伙的最高領導人, //"擒賊先擒王"原則 int getf(int v) { if(f[v]==v) return v; else { //這裡是路徑壓縮,每次在函式返回的時候,順便把路上遇到的人的"BOSS"改為最後找到的祖宗編號 //也就是犯罪團伙的最高領導人編。這樣可以提高今後找到犯罪團伙的最高領導人(其實就是樹的祖先)的速度 f[v]=getf(f[v]); return f[v]; } } //這裡是合併兩子集的函式 void Merge(int v,int u) { int t1=getf(v); int t2=getf(u); if(t1!=t2) //判斷兩點是否在同一個集合裡,即是否為同一個祖先 f[t2]=t1; //"靠左"原則,左邊變成右邊的BOSS。即把右邊的集合,作為左邊集合的子集和 //經過路徑壓縮後,將f[u]的根的值也賦值為v的祖先f[t1] } int main() { int i,x,y; scanf("%d%d",&n,&m); init(); for(i=1;i<=m;i++) { //開始合併犯罪團伙 scanf("%d %d",&x,&y); Merge(x,y); } sum=0; //最後掃描有多少個獨立的犯罪團伙 for(i=1;i<=n;i++) if(f[i]==i) sum++; printf("%d\n",sum); return 0; }
摘自《啊哈!演算法》
相關推薦
犯罪團伙(並查集)
題目描述: 快過年了,犯罪分子們也開始為年終獎"奮鬥"作案了。小哼的家鄉出現了多次搶劫事件。由於強盜人數過於龐大。作案頻繁,警方想查清楚到底有幾個犯罪團伙實在太不容易了,不過警察叔叔還是蒐集到了一些證據,需要咱們幫忙分析一下: 例: 現在有10個強盜 1號強盜與2號強
Codevs2597 團伙 並查集
Codevs2597 團伙 還是做題太少啊,然而NOIP了。 程式碼簡單易懂: #include <cstdio> #include <cstring> #include
【bzoj1370】[Baltic2003]Gang團伙 並查集
這可能是我最後幾天在機房寫題了,希望各位隊爺NOI能那個好成績吧。 每個點拆成兩個點,每一條邊,如果是朋友則直接連邊,如果是仇人,則從x向y+n連一條有向邊,從y向x+n連一條有向邊,這樣所有視y為敵
【洛谷1892】團伙 並查集
題意 題面說的很清楚 #include<iostream> #include<cstring> #include<cstdio> using namespac
bzoj 1370 團伙 並查集
題意:n個人,朋友的朋友是我的朋友,敵人的敵人是我的朋友,互為朋友的組成一個團伙,問團伙的數量 並查集入門題 把一個人拆成兩個,x表示朋友集合,n+x表示敵人集合 朋友的朋友是我的朋友:直接合並x和y
2597 團伙(並查集)
題目描述 Description 1920年的芝加哥,出現了一群強盜。如果兩個強盜遇上了,那麼他們要麼是朋友,要麼是敵人。而且有一點是肯定的,就是: 我朋友的朋友是我的朋友; 我敵人的敵人也是我的朋友。 兩個強盜是同一團伙的條件是當且僅當他們是朋友。現在給你一些
CodeVS-2597 團伙(並查集)
題目:CodeVS-2597 題目連結:http://codevs.cn/problem/2597/ 題目: 2597 團伙 時間限制: 1 s 空間限制: 128000 KB
bzoj1370 團伙 【並查集】
題目描述 在某城市裡住著 n 個人,任何兩個認識的人不是朋友就是敵人,而且滿足: 1、我朋友的朋友是我的朋友; 2、我敵人的敵人是我的朋友; 所有是朋友的人組成一個團伙。告訴你關於這 n 個人的
P1892-團伙【圖論,並查集】
正題 大意 兩個人如果認識就只有兩種關係,敵人或朋友 而: 朋友的朋友是朋友 敵人的敵人是朋友 (敵人之間也可能是敵人) 求團伙總數 解題思路 就像做食物鏈一樣,如
poj 1182 (帶權並查集)
ios int 查找 食物 spa script ble 距離 輸出 食物鏈 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 71361 Accepted: 21131 Des
BZOJ 4569 [Scoi2016]萌萌噠 ——ST表 並查集
oid include long long amp else n) div 每一個 並查集 好題。 ST表又叫做稀疏表,這裏利用了他的性質。 顯然每一個條件可以分成n個條件,顯然過不了。 然後發現有許多狀態是重復的,首先考慮線段樹,沒什麽卵用。 然後ST表,可以每一層表示對
1013. Battle Over Cities (25)(連通分量個數 、 並查集)
mage conn pen view con input case scanf print It is vitally important to have all the cities connected by highways in a war. If a city is
HDU4126Genghis Khan the Conqueror(最小生成樹+並查集)
mini info struct waiting other desc dfa tle ngs Genghis Khan the Conqueror Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 327
hdoj-1856-More is better【並查集】
sub ont max ash cer careful gin search std More is better Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 327680/102400 K (Java/Ot
【bzoj1015】【JSOI2008】【星球大戰】【並查集+離線】
urn new span fin mar tdi mem 一次 esp Description 非常久曾經。在一個遙遠的星系,一個黑暗的帝國靠著它的超級武器統治者整個星系。某一天,憑著一個偶然的機遇,一支反抗軍摧毀了帝國的超級武器。並攻下了星系中差點兒全部的星球。這些
可持久化並查集加強版 BZOJ 3674
log 歷史 clear 必須 new 路徑壓縮 都是 return 父節點 http://www.lydsy.com/JudgeOnline/problem.php?id=3674 3674: 可持久化並查集加強版 Time Limit: 15 Sec Memory
poj 1703 Find them, Catch them(種類並查集和一種巧妙的方法)
ogr not 帶權並查集 drag single sca course first req Find them, Catch them Time Limit: 1000MS Memory Limit: 10000K Total Submissions
[BZOJ 3211]花神遊歷各國(並查集+樹狀數組)
image fin 不為 names src scrip 樹狀數組 add bsp Description Solution 樹狀數組單點修改區間查詢 我們知道一個數n最多修改loglogn次就會變為1 並查集維護每個數右邊第一個不為1的位置 #inclu
<算法><Union Find並查集>
添加 容易 fin 程序 zh-cn 過程 表現 應用場景 union Intro 想象這樣的應用場景:給定一些點,隨著程序輸入,不斷地添加點之間的連通關系(邊),整個圖的連通關系也在變化。這時候我們如何維護整個圖的連通性(即判斷任意兩個點之間的連通性)呢? 一個比較簡單
BZOJ 3674 可持久化並查集加強版(主席樹變形)
als ret desc scan sync scanf ops 只需要 ica 3673: 可持久化並查集 by zky Time Limit: 5 Sec Memory Limit: 128 MB Submit: 2515 Solved: 1107 [