NC16591 關押罪犯 並查集

2021-10-06 22:57:06 字數 1331 閱讀 7939

題解:很明顯的並查集,但因為它們帶有權值,所以我們先要把他排序,我們要盡可能讓危害大的罪犯在兩個監獄裡(這裡有一點貪心的味道)。

1.首先我們把它門按照之間的影響值從大到小排序。

2.假設a與b是敵人,那麼我們吧a,b分開放置,並且記錄a的敵人是b,b的敵人是a

3.又假設a與c是敵人,這樣的話我們記錄一下c的敵人是a,這樣的話,b和c就在乙個監獄裡,所以把他倆合併起來,怎麼知道b與c在乙個監獄呢,這是因為我們用rem陣列記錄了a的敵人,敵人的敵人是朋友,所以b,c合併

4.又說b和c是敵人,但是他倆已經被分到乙個監獄了,所以直接輸出他倆之間的影響值。

怎麼證明他倆之間的影響值是最小的呢,因為我們之前已經按照權值排序了,已經盡可能不讓權值大的在一起,所以這樣輸出是對的。

也可以這樣理解,如果不把他倆放在一起,而分開放置,那麼前面一定會有衝突的,並且前面的權值較大,所以不是最優解。

**:

/*keep on going never give up*/

#pragma gcc optimize(3,"ofast","inline")

#include

const

int maxn =

1e5+10;

const

int maxn =

0x3f3f3f3f

;const

int minn =

0xc0c0c00c

;typedef

long

long ll;

const

int mod =

100000000

;using

namespace std;

struct wazxya[maxn]

;struct rule};

int f[maxn]

,rem[maxn]

;int

ifind

(int x)

void

mer(

int x,

int y)

intmain()

if(!rem[a[i]

.x]) rem[a[i]

.x]=a[i]

.y;else

mer(rem[a[i]

.x],a[i]

.y);if(

!rem[a[i]

.y]) rem[a[i]

.y]=a[i]

.x;else

mer(rem[a[i]

.y],a[i]

.x);

} cout<<

0

}

並查集 關押罪犯

題目描述 s城現有兩座監獄,一共關押著n名罪犯,編號分別為1 n。他們之間的關係自然也極不和諧。很多罪犯之間甚至積怨已久,如果客觀條件具備則隨時可能爆發衝突。我們用 怨氣值 乙個正整數值 來表示某兩名罪犯之間的仇恨程度,怨氣值越大,則這兩名罪犯之間的積怨越多。如果兩名怨氣值為c的罪犯被關押在同一監獄...

NOIP 關押罪犯(並查集)

時間限制 1 sec 記憶體限制 128 mb 提交 94 解決 32 提交 狀態 討論版 命題人 admin s城現有兩座監獄,一共關押著n名罪犯,編號分別為1 n。他們之間的關係自然也極不和諧。很多罪犯之間甚至積怨已久,如果客觀條件具備則隨時可能爆發衝突。我們用 怨氣值 乙個正整數值 來表示某兩...

並查集的補集 (關押罪犯)

定義元素t的逆為t,t一定不在包含t的集合裡 因為對於兩個需要分配在不同集合的元素a b,我們並不知道具體該怎麼分,所以就令元素a和b在一起,元素b和a在一起。避免了直接分配a,b到哪乙個集合的問題!自己模擬最快明白 例題 關押罪犯2010年noip全國聯賽提高組 include using nam...