tyvj P1403 關押罪犯 題解

2022-07-17 07:57:08 字數 3846 閱讀 9534

p1403[noip2010]關押罪犯

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

每年年末,警察局會將本年內監獄中的所有衝突事件按影響力從大到小排成乙個列表,然後上報到s 城z 市長那裡。公務繁忙的z 市長只會去看列表中的第乙個事件的影響力,如果影響很壞,他就會考慮撤換警察局長。

在詳細考察了n 名罪犯間的矛盾關係後,警察局長覺得壓力巨大。他準備將罪犯們在兩座監獄內重新分配,以求產生的衝突事件影響力都較小,從而保住自己的烏紗

帽。假設只要處於同一監獄內的某兩個罪犯間有仇恨,那麼他們一定會在每年的某個時候發生摩擦。那麼,應如何分配罪犯,才能使z 市長看到的那個衝突事件的

影響力最小?這個最小值是多少?

輸入檔案的每行中兩個數之間用乙個空格隔開。

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

接下來的m 行每行為三個正整數aj,bj,cj,表示aj 號和bj 號罪犯之間存在仇恨,其怨氣值為cj。資料保證1<=aj輸出共1 行,為z 市長看到的那個衝突事件的影響力。如果本年內監獄中未發生任何衝突事件,請輸出0。

4 6

1 4 2534

2 3 3512

1 2 28351

1 3 6618

2 4 1805

3 4 12884

3512
【資料範圍】

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

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

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

——————————————我是分割線————————————————————————

【解法一】

使用並查集,最快的方法。

一開始沒注意資料範圍,陣列開小了,導致最後4個點re,乙個多鐘頭才查出來t_t

1 #include2 #include3 #include4 #include5 #include6 #include7 #include8 #include9 #include10 #include11

#define maxn 100001

12#define f(i,j,k) for(int i=j;i<=k;i++)

13#define m(a,b) memset(a,b,sizeof(a))

14#define ff(i,j,k) for(int i=j;i>=k;i--)

15#define inf 0x7fffffff

16#define p 23333333333333333

17using

namespace

std;

18int

read()

21while(ch>='

0'&&ch<='9')

22return x*f;23}

24int

f[maxn];

25struct

sd26

edge[maxn];

32bool cmp(const sd& x,const sd&y)

3336

int find(int

x) 37

40int

head[maxn];

41int cnt=1;42

int addedge(int x,int y,int

v)43

51int

main()

5263

intx,y;

64for(int i=1;i<=n*2;i++)

65 f[i]=i;

66 sort(edge+1,edge+m+1

,cmp);

67 f(i,1

,m)75 f[y]=find(edge[i].a+n);

76 f[x]=find(edge[i].b+n);77}

78 cout<

<

79return0;

80 }

tyvj 1403(1)

【解法二】

二分+二分圖染色

前向星儲存資訊,用a陣列單獨儲存怨氣值,增加0(若無衝突,則輸出0。

將a陣列從小到大排序,二份答案。

若當前大於等於mid的關係能滿足二分圖的要求(用到二分圖染色判定),則說明解小於等於mid,r=mid,否則說明解大於mid,就將l賦值為mid+1。

開了全域性變數n、m後在主函式中又開了一次,導致錯誤,只輸出0。又查了乙個鐘頭........(大哭)

1/*2

problem:tyvj 1403

3by:s.b.s.4*/

5 #include6 #include7 #include8 #include9 #include10 #include11 #include12 #include13 #include14 #include15

#define maxn 200001

16#define f(i,j,k) for(int i=j;i<=k;i++)

17#define m(a,b) memset(a,b,sizeof(a))

18#define ff(i,j,k) for(int i=j;i>=k;i--)

19#define inf 0x7fffffff

20using

namespace

std;

21int

read()

24while(ch>='

0'&&ch<='9')

25return x*f;26}

27struct

edge

28edge[maxn];

33int

tot,it,n,m;

34int

head[maxn],b[maxn],a[maxn];

35bool

pd;36 inline void addedge(int x,int y,int

z)37

43int cmp(int a,int

b) 44

47 inline void dfs(int x,int

d)4864}

65}66}

67}68 inline bool ok(int

mm)69

78return

pd;79}80

intmain()

8197

//for(int i=1;i<=tot;i++)cout<98 a[1]=0

;99 sort(a+1,a+1+m,cmp);

100//

for(int i=1;i<=m+1;i++)cout<101

//cout<102

int left=1,right=m+1

,mid;

103while(left

104110 cout

111return0;

112}

113/*

1144 6

1151 4 2534

1162 3 3512

1171 2 28351

1181 3 6618

1192 4 1805

1203 4 12884

121*/

tyvj 1403(2)

關押罪犯題解

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

noip2010 關押罪犯 題解

這道題的初始思路肯定會往貪心上面靠吧。很明顯首先需要對所有的衝突值從大到小排乙個序,因為是從小到大處理,所以肯定是衝突的放在兩個不同的監獄裡,一直到不得不衝突的為止。主要問題在於 不能直接通過標記罪犯所在的監獄編號來記錄衝突!因為你不能確定把當前罪犯放在監獄1裡或者監獄2裡,與後面的罪犯衝突的情況下...

題解 P1525 關押罪犯

這道題是一道比較好的並查集的題目,蒟蒻頓時感覺我學了乙個假的並查集。首先,這道題的意思是 給你 n 個點,將他們任意分成兩邊,求這些點之前權值最大的邊盡量的小,求這個值。我們如何用並查集來做呢?首先,我們將所有邊從大到小排序,對於每兩個點 x 和 y 我們將 x 和 y 的敵人放一起,x 的敵人和 ...