洛谷1111 修復公路

洛谷1111 修復公路

本題地址: http://www.luogu.org/problem/show?pid=1111

題目背景
A地區在地震過後,連接所有村莊的公路都造成了損壞而無法通車。政府派人修復這些公路。
題目描述
給出A地區的村莊數N,和公路數M,公路是雙向的。並告訴你每條公路的連着哪兩個村莊,並告訴你什麼時候能修完這條公路。問最早什麼時候任意兩個村莊能夠通車,即最早什麼時候任意兩條村莊都存在至少一條修復完成的道路(可以由多條公路連成一條道路)
輸入輸出格式
輸入格式:
第1行兩個正整數N,M
下面M行,每行3個正整數x, y, t,告訴你這條公路連着x,y兩個村莊,在時間t時能修復完成這條公路。
輸出格式:
如果全部公路修復完畢仍然存在兩個村莊無法通車,則輸出-1,否則輸出最早什麼時候任意兩個村莊能夠通車。

輸入輸出樣例
輸入樣例#1:
4 4
1 2 6
1 3 4
1 4 5
4 2 3
輸出樣例#1:
5

說明
N<=1000,M<=100000
x<=N,y<=N,t<=100000

題解:
洛谷1111 修復公路

本題地址: http://www.luogu.org/problem/show?pid=1111

題目背景
A地區在地震過後,連接所有村莊的公路都造成了損壞而無法通車。政府派人修復這些公路。
題目描述
給出A地區的村莊數N,和公路數M,公路是雙向的。並告訴你每條公路的連着哪兩個村莊,並告訴你什麼時候能修完這條公路。問最早什麼時候任意兩個村莊能夠通車,即最早什麼時候任意兩條村莊都存在至少一條修復完成的道路(可以由多條公路連成一條道路)
輸入輸出格式
輸入格式:
第1行兩個正整數N,M
下面M行,每行3個正整數x, y, t,告訴你這條公路連着x,y兩個村莊,在時間t時能修復完成這條公路。
輸出格式:
如果全部公路修復完畢仍然存在兩個村莊無法通車,則輸出-1,否則輸出最早什麼時候任意兩個村莊能夠通車。

輸入輸出樣例
輸入樣例#1:
4 4
1 2 6
1 3 4
1 4 5
4 2 3
輸出樣例#1:
5

說明
N<=1000,M<=100000
x<=N,y<=N,t<=100000

題解:
簡單的並查集問題,我在洛谷的試煉場第一題。
思路有點類似最小生成樹kruskal算法只需要把所有邊按照時間從小到大排序(即修路的順序)
用sum記錄當前有多少個連通圖(初始爲n),當只有一個連通圖時任意兩個村莊能夠通車,輸出即可
至於判定連通圖,是經典並查集

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>

using namespace std;
const int maxm=100010, maxn=1010;
struct Edge{
    int u, v, t;
    bool operator <  (const Edge &rhs) const{
        return t<rhs.t;
    }
}e[maxm];
int fa[maxn];
int find(int x){
    return fa[x] = (fa[x]==x) ? x : find(fa[x]);
}
int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i=1; i<=m; i++)
        scanf("%d%d%d", &e[i].u,  &e[i].v, &e[i].t);
    sort(e+1, e+1+m);
    int sum=n;
    for (int i=1; i<=n; i++) fa[i]=i;
    int ans=-1;
    for (int i=1; i<=m; i++)
    {
        int fx=find(e[i].u), fy=find(e[i].v);
        if (fx!=fy){
            fa[fy]=fx;
            sum--;
            if (sum==1) {ans=e[i].t; break;}
        }
    }
    printf("%d", ans);
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章