10 noip 關押罪犯 解題報告

2021-06-28 15:47:40 字數 3342 閱讀 6353

題目描述 

description

s 城現有兩座監獄,一共關押著n 名罪犯,編號分別為1~n。他們之間的關係自然也極

不和諧。很多罪犯之間甚至積怨已久,如果客觀條件具備則隨時可能爆發衝突。我們用「怨

氣值」(乙個正整數值)來表示某兩名罪犯之間的仇恨程度,怨氣值越大,則這兩名罪犯之

間的積怨越多。如果兩名怨氣值為c 的罪犯被關押在同一監獄,他們倆之間會發生摩擦,並

造成影響力為c 的衝突事件。

每年年末,警察局會將本年內監獄中的所有衝突事件按影響力從大到小排成乙個列表,

然後上報到s 城z 市長那裡。公務繁忙的z 市長只會去看列表中的第乙個事件的影響力,

如果影響很壞,他就會考慮撤換警察局長。

在詳細考察了n 名罪犯間的矛盾關係後,警察局長覺得壓力巨大。他準備將罪犯們在

兩座監獄內重新分配,以求產生的衝突事件影響力都較小,從而保住自己的烏紗帽。假設只

要處於同一監獄內的某兩個罪犯間有仇恨,那麼他們一定會在每年的某個時候發生摩擦。那

麼,應如何分配罪犯,才能使z 市長看到的那個衝突事件的影響力最小?這個最小值是少?

輸入描述 

input description

第一行為兩個正整數n 和m,分別表示罪犯的數目以及存在仇恨的罪犯對數。

接下來的m 行每行為三個正整數aj,bj,cj,表示aj 號和bj 號罪犯之間存在仇恨,其怨氣值為cj。資料保證,且每對罪犯組合只出現一次。

輸出描述 

output description

共1 行,為z 市長看到的那個衝突事件的影響力。如果本年內監獄

中未發生任何衝突事件,請輸出0。

樣例輸入 

sample input

4 61 4 2534

2 3 3512

1 2 28351

1 3 6618

2 4 1805

3 4 12884

樣例輸出 

sample output

3512

資料範圍及提示 

data size & hint

罪犯之間的怨氣值如下面左圖所示,右圖所示為罪犯的分配方法,市長看到的衝突事件

影響力是3512(由2 號和3 號罪犯引發)。其他任何分法都不會比這個分法更優。

【資料範圍】

對於30%的資料有n≤ 15。

對於70%的資料有n≤ 2000,m≤ 50000。

對於100%的資料有n≤ 20000,m≤ 100000。

先談一下儲存方式吧,這個題目肯定不能建二維陣列,於是我選擇了記錄型別。

這個題目的做法很多,我採取的是並查集的做法,製作了兩個陣列,乙個用來儲存他的敵人,也就是肯定不和他在同乙個監獄的人,另乙個是他的獄友。

先將怒氣值從大到小排序一遍,從大到小進行判斷。如果兩個人都沒有敵人,那麼就把對方作為自己的敵人。如果對方已經有敵人了,那麼自己和對方的敵人就要成為獄友了。如果兩個人是獄友,那麼他們的怒氣值就是答案了。

判斷兩個人是不是獄友,用並查集就可以。因為我們不斷規避大的怒氣值的出現,一旦出現了乙個怒氣值無法規避,那麼,這個怒氣值就是該題目的答案。

**風格略渣,不喜勿噴。

1

type

2 re=record //記錄格式

3x:longint;

4y:longint;

5k:longint;

6end;7

var8

x,y,i,j,n,m,ans,k,t:longint;

9 a:array[1..100000]of

re;10 b,c:array[1..20000]of longint; //b儲存敵人 c儲存獄友

1112

function union(k:longint):longint; //並查集

13begin

14if c[k]=k then

exit(k)

15else

exit(union(c[k]));

16end;17

18procedure hb(x,y:longint); //處理兩個人資訊

19begin

20if b[x]=0

then b[x]:=y;

21if b[y]=0

then b[y]:=x;

22 c[union(y)]:=union(b[x]);

23 c[union(x)]:=union(b[y]);

24end;25

26procedure

qsort(h,t:longint);

27var

28i,j,x:longint;

29k:re;

30begin

31 i:=h;

32 j:=t;

33 x:=a[(h+t) div

2].k;

34while (ido

35begin

36while (a[i].k>x) do

inc(i);

37while (a[j].kdo

dec(j);

38if (i<=j) then

39begin

40 k:=a[i];

41 a[i]:=a[j];

42 a[j]:=k;

43inc(i);

44dec(j);

45end;46

end;

47if (ithen

qsort(i,t);

48if (hthen

qsort(h,j);

49end;50

51begin

52readln(n,m);

53for i:=1

to n do

54 c[i]:=i;

55for i:=1

to m do

56begin

57readln(x,y,k);

58 a[i].x:=x;

59 a[i].y:=y;

60 a[i].k:=k;

61end

;62 qsort(1

,m);

63 ans:=0;64

for i:=1

to m do

65if union(a[i].x)=union(a[i].y) then //判斷兩人是否是獄友

66begin ans:=a[i].k; break; end

67else

68hb(a[i].x,a[i].y);

69 writeln(ans); //如果到最後都沒發生衝突,ans就等於0

70end.

NOIP2010提高組 關押罪犯 解題報告

解題思路 根據題目描述要將n名罪犯分在2座監獄中,可以考慮用二分圖來解答問題,將每名罪犯看為乙個點,存在仇恨的罪犯間連一條無向邊。要使發生衝突的影響力最小,這裡給出兩種解答方法,方法一 運用一點貪心的思想,讓衝突小的發生來使得衝突大的不發生,即將邊按權值由小到大進行排序,刪除當前權值最小的邊,判斷所...

NOIP 關押罪犯

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

noip2010 關押罪犯

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