zcmu-1960
1960: 關(guān)押罪犯
Time Limit:?1 Sec??Memory Limit:?128 MBSubmit:?22??Solved:?7
[Submit][Status][Web Board]
Description
S 城現(xiàn)有兩座監(jiān)獄,一共關(guān)押著 N 名罪犯,編號(hào)分別為 1~N。他們之間的關(guān)系自然也極 不和諧。很多罪犯之間甚至積怨已久,如果客觀條件具備則隨時(shí)可能爆發(fā)沖突。我們用“怨 氣值”(一個(gè)正整數(shù)值)來表示某兩名罪犯之間的仇恨程度,怨氣值越大,則這兩名罪犯之 間的積怨越多。如果兩名怨氣值為 c 的罪犯被關(guān)押在同一監(jiān)獄,他們倆之間會(huì)發(fā)生摩擦,并 造成影響力為 c 的沖突事件。 每年年末,警察局會(huì)將本年內(nèi)監(jiān)獄中的所有沖突事件按影響力從大到小排成一個(gè)列表, 然后上報(bào)到 S 城 Z 市長(zhǎng)那里。公務(wù)繁忙的 Z 市長(zhǎng)只會(huì)去看列表中的第一個(gè)事件的影響力, 如果影響很壞,他就會(huì)考慮撤換警察局長(zhǎng)。 在詳細(xì)考察了 N 名罪犯間的矛盾關(guān)系后,警察局長(zhǎng)覺得壓力巨大。他準(zhǔn)備將罪犯?jìng)冊(cè)?兩座監(jiān)獄內(nèi)重新分配,以求產(chǎn)生的沖突事件影響力都較小,從而保住自己的烏紗帽。假設(shè)只 要處于同一監(jiān)獄內(nèi)的某兩個(gè)罪犯間有仇恨,那么他們一定會(huì)在每年的某個(gè)時(shí)候發(fā)生摩擦。那 么,應(yīng)如何分配罪犯,才能使 Z 市長(zhǎng)看到的那個(gè)沖突事件的影響力小?這個(gè)小值是多少?
Input
對(duì)于 30%的數(shù)據(jù)有 N≤15。
對(duì)于 70%的數(shù)據(jù)有 N≤2000,M≤50000。
對(duì)于 100%的數(shù)據(jù)有 N≤20000,M≤100000。
Output
輸出文件 prison.out 共 1 行,為 Z 市長(zhǎng)看到的那個(gè)沖突事件的影響力。如果本年內(nèi)監(jiān)獄 中未發(fā)生任何沖突事件,請(qǐng)輸出 0。
Sample Input
4 61 4 25342 3 35121 2 283511 3 66182 4 18053 4 12884Sample Output
3512HINT
思路:用并查集表示每個(gè)犯人之間的關(guān)系,在同一個(gè)集合中則說明兩人在同一個(gè)監(jiān)獄,反之則不在同一個(gè)監(jiān)獄。?
用類似于克魯斯卡爾的方法,先將邊排序,然后按照仇恨值的大小從大到小處理。對(duì)于每一組,先看兩個(gè)人能不能加入不同的集合,?
如果可以,將兩人加入不同的集合,如果不可以,則輸出該組仇恨值。?
用補(bǔ)集來表示兩個(gè)點(diǎn)不在一個(gè)集合中。如a和b’在同一個(gè)集合中,則a和b不在同一個(gè)集合中,不能把b直接加入另一個(gè)集合,因?yàn)闀?huì)對(duì)后面的結(jié)果產(chǎn)生影響。?
如,3和4不在同一個(gè)集合中,但是我們現(xiàn)在不知道究竟是3在第一個(gè)監(jiān)獄還是4在第一個(gè)監(jiān)獄,所以此時(shí)用3和4‘在同一個(gè)集合中來表示3和4不在同一個(gè)集合中。
代碼:
#include<algorithm> #include<iostream> #include<cstdio> #include<cstring> using namespace std; struct node {int a , b , c; }; const int N = 100000 + 50; node man[N]; int p[N]; bool cmp(node a , node b) {return a.c > b.c; } int find(int x) {return x == p[x]?x:x=find(p[x]); } int main(int argc, char const *argv[]) {int n , m;cin >> n >> m;for (int i = 0; i < m; ++i)scanf("%d%d%d", &man[i].a, &man[i].b, &man[i].c);for (int i = 1; i <= 2*n; ++i){p[i] = i;}sort(man , man + m , cmp);for (int i = 0; i < m; ++i){int x = find(man[i].a); int y = find(man[i].b);if(x == y){cout << man[i].c << endl;return 0;}p[x] = find(man[i].b + n);p[y] = find(man[i].a + n);}printf("0\n");return 0; }
總結(jié)
- 上一篇: 数据结构之malloc()函数动态内存分
- 下一篇: 大数的相加 乘 余 幂