1. 程式人生 > >18.12.16 [NOIP2010]關押罪犯(並查集)

18.12.16 [NOIP2010]關押罪犯(並查集)

描述

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

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

在詳細考察了N 名罪犯間的矛盾關係後,警察局長覺得壓力巨大。他準備將罪犯們在兩座監獄內重新分配,以求產生的衝突事件影響力都較小,從而保住自己的烏紗帽。假設只要處於同一監獄內的某兩個罪犯間有仇恨,那麼他們一定會在每年的某個時候發生摩擦。

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

輸入

輸入檔案的每行中兩個數之間用一個空格隔開。第一行為兩個正整數N 和M,分別表示罪犯的數目以及存在仇恨的罪犯對數。接下來的M 行每行為三個正整數aj,bj,cj,表示aj 號和bj 號罪犯之間存在仇恨,其怨氣值為cj。資料保證1<aj=<=bj<=n ,0="" <="" cj≤="" 1,000,000,000,且每對罪犯組合只出現一次。<="" dd="">輸出共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。

 1 #include <iostream>
 2 #include <string.h>
 3 #include <algorithm>
 4 #include <stack>
 5 #include <string>
 6 #include <math.h>
 7 #include <queue>
 8 #include <stdio.h>
 9
#include <string.h> 10 #include <vector> 11 #include <fstream> 12 #define maxn 100005 13 #define inf 999999 14 #define cha 127 15 using namespace std; 16 17 struct node { 18 int x, y; 19 int anger; 20 }all[maxn]; 21 int n, m; 22 int p[20005],rela[20005];//0 same 1 dif 23 bool cmp(node a,node b){ 24 return a.anger > b.anger; 25 } 26 27 int parent(int x) { 28 if (p[x] == x) 29 return x; 30 int px = parent(p[x]); 31 rela[x] = (rela[x] + rela[p[x]]) % 2; 32 p[x] = px; 33 return p[x]; 34 } 35 36 void merge(int x,int y) { 37 int px = parent(x), py = parent(y); 38 p[px] = py; 39 rela[px] = (rela[x] + rela[y] + 1) % 2; 40 } 41 42 bool same(int x, int y) { 43 int px = parent(x), py = parent(y); 44 if (px == py) 45 return true; 46 return false; 47 } 48 49 void solve() { 50 for (int i = 1; i <= m; i++) { 51 bool flag; 52 if (flag=same(all[i].x, all[i].y)&&rela[all[i].x]==rela[all[i].y]) { 53 printf("%d\n", all[i].anger); 54 return; 55 } 56 if (flag)continue; 57 merge(all[i].x, all[i].y); 58 } 59 printf("0\n"); 60 } 61 62 void init() { 63 scanf("%d%d", &n, &m); 64 for (int i = 1; i <= n; i++) 65 p[i] = i; 66 for (int i = 1; i <= m; i++) 67 scanf("%d%d%d", &all[i].x, &all[i].y, &all[i].anger); 68 sort(all + 1, all + m + 1,cmp); 69 solve(); 70 } 71 72 int main() 73 { 74 init(); 75 return 0; 76 }
View Code