一道感覺不錯的並查集的題目
我們先將每一組矛盾關係按照衝突值從大到小排序,然後順序掃瞄一遍,讓衝突值大的兩個人盡可能不在乙個監獄裡,如果不能滿足,那麼答案就是這組關係的矛盾值。如果所有的矛盾都不會發生,那麼答案就是0.
之後我們建立並查集,另外定義乙個輔助的陣列d表示每乙個人的乙個敵人。我們掃瞄每一對關係,如果這兩個人為了滿足前面的條件已經在同一所監獄,那麼答案就是他們的衝突值。否則,我們檢查這兩個人分別於對方的敵人合併即可。
1 #include 2 #include 3 #include 4 #include 5ac codeusing
namespace
std;
6 typedef long
long
ll;7
struct
node
12 }aa[100010
];13
intn,m;
14int f[100010],d[100010
];15
int find(int
x) 19
void add(int x,int
y) 24
intmain()
30 sort(aa+1,aa+m+1
);31 reverse(aa+1,aa+m+1
);32
for(int i=1;i<=m;i++)
37if(!d[aa[i].a]) d[aa[i].a]=aa[i].b;
38else
add(aa[i].b,d[aa[i].a]);
39if(!d[aa[i].b]) d[aa[i].b]=aa[i].a;
40else
add(aa[i].a,d[aa[i].b]);41}
42 puts("0"
);43
return0;
44 }
noip2010 關押罪犯
s 城現有兩座監獄,一共關押著n 名罪犯,編號分別為1 n。他們之間的關係自然也極 不和諧。很多罪犯之間甚至積怨已久,如果客觀條件具備則隨時可能爆發衝突。我們用 怨 氣值 乙個正整數值 來表示某兩名罪犯之間的仇恨程度,怨氣值越大,則這兩名罪犯之 間的積怨越多。如果兩名怨氣值為c 的罪犯被關押在同一監...
NOIP2010關押罪犯
s 城現有兩座監獄,一共關押著n 名罪犯,編號分別為1 n。他們之間的關係自然也極不和諧。很多罪犯之間甚至積怨已久,如果客觀條件具備則隨時可能爆發衝突。我們用 怨氣值 乙個正整數值 來表示某兩名罪犯之間的仇恨程度,怨氣值越大,則這兩名罪犯之間的積怨越多。如果兩名怨氣值為c 的罪犯被關押在同一監獄,他...
NOIP 2010 關押罪犯
題目描述 s 城現有兩座監獄,一共關押著n 名罪犯,編號分別為1 n。他們之間的關係自然也極不和諧。很多罪犯之間甚至積怨已久,如果客觀條件具備則隨時可能爆發衝突。我們用 怨氣值 乙個正整數值 來表示某兩名罪犯之間的仇恨程度,怨氣值越大,則這兩名罪犯之間的積怨越多。如果兩名怨氣值為c 的罪犯被關押在同...