m = es.size();
vector v1,v2;
for(int i=0;i<m;i++) edges.push_back(Edge(es[i][0],es[i][1],es[i][2],i));
sort(edges.begin(),edges.end());
int minCost = kruskal(0,-1);
for(int i=0;i<m;i++){
int newCost1 = kruskal(1,i);
int newCost2 = kruskal(2,i);
// 删除这条边
if(newCost2>minCost) v1.push_back(edges[i].id);
if(newCost2 == minCost && newCost1==minCost) v2.push_back(edges[i].id);
}
return {v1,v2};
}
int kruskal(int op,int index){
UF uf;
int res = 0, cnt = 0;
if(op==1) {
res += edges[index].w, cnt = 1;
uf.merge(edges[index].u,edges[index].v);
}
for(int i=0;i<m;i++){
if(op && index == i) continue;
if(uf.merge(edges[i].u,edges[i].v)){
res += edges[i].w;
cnt++;
}
}
if(cnt<n-1) return 1e9;
return res;
}
};
用Java再做一遍:
class UF{
int[] f;
public UF() {
this.f = new int[110];
for(int i=1;i<110;i++) f[i] = i;
}
int find(int x){
return x==f[x]?x:(f[x] = find(f[x]));
}
boolean merge(int x,int y){
int fx = find(x);
int fy = find(y);
if(fx==fy) return false;
f[find(x)] = find(y);
return true;
}
}
class Solution {
int[][] es;
int n,m;
public List<List> findCriticalAndPseudoCriticalEdges(int n, int[][] edges) {
this.n = n;
this.m = edges.length;
es = new int[m][4];
for(int i=0;i<m;i++){
for(int j=0;j<3;j++){
es[i][j] = edges[i][j];
}
es[i][3] = i;
}
// 各种排序方式
Arrays.sort(es, Comparator.comparingInt(e -> e[2]));
// Arrays.sort(es, (e1,e2)->e1[2]-e2[2]);
// Arrays.sort(es, new Comparator<int[]>() {
// @Override
// public int compare(int[] o1, int[] o2) {
// return o1[2]-o2[2];
// }
// });
List must = new ArrayList<>(),notMust = new ArrayList<>();
int minCost = kruskal();
// System.out.println(minCost);
for(int i=0;i<m;i++){
if(kruskalExclude(i) > minCost){
must.add(i);
}else if(kruskalInclude(i) == minCost){
notMust.add(i);
}
}
List<List> ans = new ArrayList<>();
ans.add(must);
ans.add(notMust);
return ans;
}
// 普通的Kruskal算法
int kruskal(){
UF uf = new UF();
int cost = 0;
for(var e:es){
if(uf.merge(e[0],e[1])){
cost += e[2];
}
}
return cost;
}
// 不选某条边产生的最小生成树(也可能不能生成树)
int kruskalExclude(int id){
UF uf = new UF();
int cnt = 0, cost = 0;
for(var e:es){
if(e[3] == id) continue;
if(uf.merge(e[0],e[1])){
cost += e[2];
cnt++;
}
}
if(cnt < n-1) return Integer.MAX_VALUE;
return cost;
}
// 必选某条边产生的最小生成树
int kruskalInclude(int id){
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
795280108)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!