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