P1111 修复公路 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P1111
问题分析
读完题不难发现,这题可以用标准的并查集去做,最大的难点是如何对数据进行排序,我们需要将修路的时间从小到大排好。这里我用的是map,Map
List> list = new linkedList<>(map.entrySet()); Collections.sort(list, new Comparator >() { @Override//这里用到了匿名内部类 public int compare(Map.Entry o1, Map.Entry o2) { return o1.getValue()-o2.getValue(); } });
AC代码
import java.io.*;
import java.util.*;
public class Main {
static int[] fa;
static int[] rank;
static Map map = new HashMap<>();
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StreamTokenizer st = new StreamTokenizer(br);//当然用Scanner一样的
//数据输入
st.nextToken();int n = (int)st.nval;
st.nextToken();int m = (int)st.nval;
fa = new int[n+1];rank = new int[n+1];//数组初始化
for(int i=1;i<=m;i++){
st.nextToken();int x = (int)st.nval;
st.nextToken();int y = (int)st.nval;
st.nextToken();int t = (int)st.nval;
map.put(new int[]{x,y},t);
}
//匿名内部类Collections排序
List> list = new linkedList<>(map.entrySet());
Collections.sort(list, new Comparator>() {
@Override
public int compare(Map.Entry o1, Map.Entry o2) {
return o1.getValue()-o2.getValue();
}
});
init(n);//初始化
int ans = -1;
for(Map.Entry entry : list){
int[] k = entry.getKey();
int x = k[0];
int y = k[1];
merge(x,y);
if(isOver(n)) {//如果任意两个村庄都能通车,则跳出循环,输出最小时间
ans = entry.getValue();
break;
}
}
System.out.println(ans);
}
static void init(int n){
for(int i=1;i<=n;i++){
fa[i] = i;
rank[i] = 1;
}
}
static int find(int k){
if(fa[k] == k){
return k;
} else {
fa[k] = find(fa[k]);
return fa[k];
}
}
static void merge(int i,int j){
int x = find(i),y = find(j);
if(rank[x] >= rank[y]){
fa[y] = x;
} else {
fa[x] = y;
}
if(rank[x] == rank[y]&&x!=y){
rank[x]++;
}
}
static boolean isOver(int n){//该方法用于检测任意两个村庄是否连通
int x,y;
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
x = find(i);y = find(j);
if(x!=y) return false;
}
}
return true;
}
}



