關押罪犯洛谷1525精講!!!

題目描述
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,且每對罪犯組合只出現一次。

輸出格式:
共1 行,為Z 市長看到的那個沖突事件的影響力。如果本年內監獄中未發生任何沖突事件,請輸出0。

輸入輸出樣例
輸入樣例#1:4 61 4 25342 3 35121 2 283511 3 66182 4 18053 4 12884

輸出樣例#1:3512

說明
【輸入輸出樣例說明】罪犯之間的怨氣值如下面左圖所示,右圖所示為罪犯的分配方法,市長看到的沖突事件影響力是3512(由2 號和3 號罪犯引發)。其他任何分法都不會比這個分法更優。



【數據范圍】對于30%的數據有N≤ 15。對于70%的數據有N≤ 2000,M≤ 50000。對于100%的數據有N≤ 20000,M≤ 100000。

這里可以用一個貪心的思想來解決這個問題,要求使怨氣最大的那一個又要最小,
那我們不妨把怨氣值排個序,把怨氣值較大一對罪犯的分在兩所監獄,就這樣一直分一直分直到發生沖突(就是假設a b先被分開了,b c又被分開了,因為只有兩個監獄,所以a c絕對在一起,可現在又要分a c 了可見有矛盾),這時a c的怒氣值就是我們的最優解,為什么呢?
原因很簡單,因為是按怒氣值從大到小排好序的,分開也是從怒氣大的慢慢分開,
還是剛剛的a b c這個例子,a b怒氣第一大,ok被分開了,兩個監獄怒氣都沒了,b c怒氣第二大,又被分開了,怒氣沒了,現在a c怒氣第三大,沒辦法被分開了,只能在同一個監獄了,你說最后的解是不是a c的怒氣值?

其實思路就這樣了,下面上代碼?

#include<iostream>
#include<algorithm>
using namespace std;
struct node {
    int a, b, c;
}bad[100010];
int f[40010] = {}, n, m;;

void inti() {
    for (int i = 1; i <= n*2; i++) {
        f[i] = i;
    }
    return;
}//并查集初始化
int dfs(int s) {
    if (f[s] == s) return s;
    else {
        f[s] = dfs(f[s]);
        return f[s];
    }
}//查找結點所在集合
bool cmp(node z,node t) {
    return z.c > t.c;
}
int main() {
    scanf("%d %d", &n, &m);
    inti();
    for (int i = 1; i <= m; i++) {
        scanf("%d %d %d", &bad[i].a, &bad[i].b, &bad[i].c);
    }
    sort(bad + 1, bad + 1 + m, cmp);//按怒氣值排序
    for (int i = 1; i <= m; i++) {
        int ra = dfs(bad[i].a), rb = dfs(bad[i].b);
        if (ra == rb) {
            printf("%d", bad[i].c);
            return 0;
        }//如果發生沖突,就找到了最優解,輸出,結束程序
        f[ra] = dfs(bad[i].b + n);//沒沖突,就分到不同的監獄
        f[rb] = dfs(bad[i].a + n);
    }
    printf("0");//沒沖突事件,0,over!
    return 0;//結束!!!
}

感謝,留下一個贊Thanks?(?ω?)?!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 機器翻譯 題目背景 小晨的電腦上安裝了一個機器翻譯軟件,他經常用這個軟件來翻譯英語文章。 題目描述 這個翻譯軟件的...
    bbqub閱讀 371評論 0 0
  • 一、實驗目的 學習使用 weka 中的常用分類器,完成數據分類任務。 二、實驗內容 了解 weka 中 explo...
    yigoh閱讀 8,629評論 5 4
  • 薄衫輕浮, 發梢微濕, 風吹薄衫起, 雨滴細發濕。 手持一把油紙傘, ...
    倪薇薇閱讀 532評論 1 5
  • 03-1-88陳秀方 前幾天借了一本《眼》的繪本,這是一本獲得博洛尼亞國際童書展最佳童書獎的書,那自然是好書,因為...
    你的眼睛是窗戶閱讀 190評論 0 0
  • 感賞我的老公最愛我了,談戀愛的時候什么都聽我的,還大老遠的坐一個小時的公交車,只為給我送一杯珍珠奶茶。 感賞我的老...
    許曉凌_中閱讀 187評論 0 0