洛谷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;
}