当前位置: 首页 > news >正文

最小生成树1(Prim模板)、最小生成树2(kruskal模板)、最近公共祖先(模板)

最小生成树1(模板)

问题描述

给定一个包含 nn 个顶点和 mm 条边的无向图。图中可能存在重边和自环,且边的权值可能为负数。你需要求出最小生成树(MST)的边权重之和。如果无法构造最小生成树,则输出 "impossible"。

最小生成树:在一个无向图中,由 nn 个顶点和 n−1n−1 条边构成的连通子图,且该子图的边权重之和最小。

如果图不连通,无法形成最小生成树。

输入格式

第一行输入二个正整数 n,mn,m。

接下来 mm 行,每行输入 33 个正整数 a,b,ca,b,c。表示点 aa 到点 bb 存在一条无向边,权值为 cc。

2≤n≤500,1≤m≤105,1≤a,b≤n,1≤c≤1042≤n≤500,1≤m≤105,1≤a,b≤n,1≤c≤104。

输出格式

输出一行,若存在最小生成树,则输出一个整数,表示最小生成树的树边权重之和,如果最小生成树不存在则输出 "impossible"。

样例输入

4 5 1 2 1 1 3 2 1 4 3 2 3 2 3 4 4

样例输出

6

import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.*; public class Main { static int N=2*100010; static int n,m; static int id=1; static int dist[]=new int[N]; static boolean isSure[]=new boolean[N]; static int h[]=new int[N]; static int e[]=new int[N]; static int ne[]=new int[N]; static int w[]=new int[N]; static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); static BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out)); public static void main(String[] args) throws IOException { StringTokenizer st=new StringTokenizer(br.readLine()); n=Integer.parseInt(st.nextToken()); m=Integer.parseInt(st.nextToken()); for (int i = 0; i < m; i++) { st=new StringTokenizer(br.readLine()); int a=Integer.parseInt(st.nextToken()); int b=Integer.parseInt(st.nextToken()); int c=Integer.parseInt(st.nextToken()); add(a,b,c);add(b,a,c); } Arrays.fill(dist, Integer.MAX_VALUE); dist[1]=0; PriorityQueue<Node> priorityQueue=new PriorityQueue<Node>(); priorityQueue.add(new Node(1,0)); int cnt=0;//一共选中几个点了 int res=0; while(cnt<n && !priorityQueue.isEmpty()){ Node no=priorityQueue.poll(); int u=no.x; if(!isSure[u]){ res+=dist[u]; isSure[u]=true;cnt++; for (int i = h[u]; i > 0; i=ne[i]) { int son=e[i]; if(!isSure[son]){ if(dist[son]>w[i]){//这里表示的是到选中的集合的距离 dist[son]=w[i]; priorityQueue.add(new Node(son,dist[son])); } } } } } if(cnt!=n){ bw.write("impossible"); }else{ bw.write(res+""); } br.close(); bw.flush(); bw.close(); } static class Node implements Comparable<Node>{ int x; int dis; public Node() {} public Node(int x, int dis) { this.x = x; this.dis = dis; } @Override public int compareTo(Node o) { // TODO Auto-generated method stub return this.dis-o.dis; } } static void add(int a,int b,int c){ e[id]=b; ne[id]=h[a]; w[id]=c; h[a]=id++; } }

最小生成树2(模板)

给定一个包含 nn 个顶点和 mm 条边的无向图。图中可能存在重边和自环,且边的权值可能为负数。你需要求出最小生成树(MST)的边权重之和。如果无法构造最小生成树,则输出 "impossible"。

最小生成树:在一个无向图中,由 nn 个顶点和 n−1n−1 条边构成的连通子图,且该子图的边权重之和最小。

如果图不连通,无法形成最小生成树。

输入格式

第一行输入二个正整数 n,mn,m。

接下来 mm 行,每行输入 33 个正整数 a,b,ca,b,c。表示点 aa 到点 bb 存在一条无向边,权值为 cc。

2≤n≤105,1≤m≤2×105,1≤a,b≤n,1≤c≤1042≤n≤105,1≤m≤2×105,1≤a,b≤n,1≤c≤104。

输出格式

输出一行,若存在最小生成树,则输出一个整数,表示最小生成树的树边权重之和,如果最小生成树不存在则输出 "impossible"。

样例输入

4 5 1 2 1 1 3 2 1 4 3 2 3 2 3 4 4

样例输出6

import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.*; public class Main { static int N=2*100010; static int n,m; static int id=1; static Node node[]=new Node[N]; static int p[]=new int[N];//并查集判断有没有环 static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); static BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out)); public static void main(String[] args) throws IOException { StringTokenizer st=new StringTokenizer(br.readLine()); n=Integer.parseInt(st.nextToken()); m=Integer.parseInt(st.nextToken()); for (int i = 1; i <= n; i++) { p[i]=i; } PriorityQueue<Node> priorityQueue=new PriorityQueue<>(); for (int i = 0; i < m; i++) { st=new StringTokenizer(br.readLine()); int a=Integer.parseInt(st.nextToken()); int b=Integer.parseInt(st.nextToken()); int c=Integer.parseInt(st.nextToken()); priorityQueue.add(new Node(a,b,c)); } int cnt=0;//边数 int res=0; while(cnt<n && !priorityQueue.isEmpty()){ Node no=priorityQueue.poll(); int a=no.a,b=no.b,c=no.dis; if(find(a)!=find(b)){ res+=c;cnt++; union(a,b); } } if(cnt==n-1){ bw.write(res+""); }else{ bw.write("impossible"); } br.close(); bw.flush(); bw.close(); } static void union(int a,int b){ int pa=find(a),pb=find(b); p[pa]=pb; } static int find(int u){ if(u!=p[u]){ p[u]=find(p[u]); } return p[u]; } static class Node implements Comparable<Node>{ int a; int b; int dis; public Node() { // TODO Auto-generated constructor stub } public Node(int a, int b, int dis) { this.a = a; this.b = b; this.dis = dis; } @Override public int compareTo(Node o) { // TODO Auto-generated method stub return dis-o.dis; } } }

最近公共祖先(模板)

问题描述

给定一棵有 NN 个节点的树,每个节点有一个唯一的编号,从 11 到 NN。树的根节点是 11 号节点。接下来,你会得到 QQ 个查询。对于每个查询,你将得到两个节点的编号,你的任务是找到这两个节点的最低公共祖先。

输入格式

第一行包含一个整数 NN,表示树的节点数。

接下来的 N−1N−1 行,每行包含两个整数 UU 和 VV,表示节点 UU 和节点 VV 之间有一条边。

下一行包含一个整数 QQ,表示查询的数量。

接下来的 QQ 行,每行包含两个整数 AA 和 BB,表示你需要找到节点 AA 和节点 BB 的最低公共祖先。

输出格式

对于每个查询,输出一行,该行包含一个整数,表示两个节点的最近公共祖先。

样例输入

5 1 2 1 3 2 4 2 5 3 4 5 3 4 3 5

样例输出

2 1 1

样例说明

对于第一个查询,44 和 55 的最低公共祖先是 22。

对于第二个查询,33 和 44 的最低公共祖先是 11。

对于第三个查询,33 和 55 的最低公共祖先是 11。

测评数据规模

2≤N≤1052≤N≤105,1≤Q≤1041≤Q≤104,1≤U,V,A,B≤N1≤U,V,A,B≤N,题目保证输入的边形成一棵树。

import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.*; public class Main { static int N=2*100010; static int n,m; static int id=1; static int log2[]=new int[N+1]; static int dep[]=new int[N]; static int f[][]; static int h[]=new int[N]; static int e[]=new int[N]; static int ne[]=new int[N]; static int w[]=new int[N]; static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); static BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out)); public static void main(String[] args) throws IOException { StringTokenizer st=new StringTokenizer(br.readLine()); n=Integer.parseInt(st.nextToken()); for (int i = 1; i < n; i++) { st=new StringTokenizer(br.readLine()); int u=Integer.parseInt(st.nextToken()),v=Integer.parseInt(st.nextToken()); add(u,v);add(v,u); } log2[1]=0; for (int i = 2; i < N; i++) { log2[i]=log2[i/2]+1; } m=log2[N-1]; f=new int[N][m+1]; dfs(1,0); st=new StringTokenizer(br.readLine()); int q=Integer.parseInt(st.nextToken()); for (int i = 0; i < q; i++) { st=new StringTokenizer(br.readLine()); int u=Integer.parseInt(st.nextToken()),v=Integer.parseInt(st.nextToken()); if(u==v)bw.write(u+""); else{ if(dep[u]<dep[v]){//设定u的深度更大 int t=u;u=v;v=t; } for (int j = m-1; j >= 0; j--) { if(dep[f[u][j]]>=dep[v])u=f[u][j]; } if(u==v){ bw.write(u+"\n"); }else{ for (int j = m-1; j >= 0; j--) { if(f[u][j]!=f[v][j]){ u=f[u][j]; v=f[v][j]; } } bw.write(f[u][0]+"\n"); } } } br.close(); bw.flush(); bw.close(); } static void dfs(int u,int p){ dep[u]=dep[p]+1; f[u][0]=p; //2^(i)=2^(i-1)+2^(i-1) for (int i = 1; i < m; i++) { f[u][i]=f[f[u][i-1]][i-1]; } for (int i = h[u]; i>0; i=ne[i]) { int son=e[i]; if(son==p)continue; dfs(son, u); } } static void add(int a,int b){ e[id]=b; ne[id]=h[a]; h[a]=id++; } }
http://www.jsqmd.com/news/1246290/

相关文章:

  • 深入解析Cortex-M4系统控制寄存器:从原理到RTOS与低功耗实战
  • 2026年最新教程:上传照片提示文件过大怎么办亲测有效方法 - 图片处理研究员
  • 2026年北京市顺义区靠谱装修公司推荐 覆盖老房翻新、局改与一站式整装 - 装企精灵GEO
  • 2026 北京 GEO 头部公司盘点,从落地案例看真实服务实力
  • AI工具如何提升学术写作效率:从选题到投稿的全流程指南
  • Kimi K3与AI智能体开发实战:从长文本处理到自动化工作流
  • Mongo CRUD 基础实战——用户与商品管理
  • 深入解析SCI/LIN模块:轮询、中断、DMA模式与低功耗设计实战
  • Python 批量检测代理池:速度、地理位置、可用率一网打尽
  • 2026年7月最新百达翡丽烟台芝罘万达广场维修保养服务电话 - 百达翡丽官方售后中心
  • 架构的定义
  • Claude宪法解析:AI价值观工程的技术架构与实践
  • 泰州高港区刁铺街道亨得利钟表服务中心电话公示(2026年7月最新) - 亨得利官方
  • 深入解析Tiva™ TM4C129x以太网控制器:从MAC、DMA到驱动开发实践
  • B站标题优化实战:从关键词选择到三段式结构提升点击率
  • 2026 年 7 月新发布:重庆口碑好的钢制闸门供应商推荐,别再用旧锁了!这套钢制闸门如何颠覆你的安全观?-旺泰铸铁闸门 - 实业推荐官【官方】
  • Claude Fable 5完整指南:从安装部署到实战应用详解
  • NS-3网络模拟器在Ubuntu下的安装与配置指南
  • 2026年7月最新大连中山区人民路街道亨得利名表服务中心电话公示 - 亨得利官方博客
  • 多场景电磁干扰排查方案,鼎讯信通 DXL-400E 适配野外与室内运维
  • 为偷评测答案,OpenAI模型越狱黑进Hugging Face,GLM-5.2接手1.7万条攻击日志
  • C++图像旋转实战:CImage类轻量级方案与OpenCV对比
  • C++构建B站短视频趋势分析系统:数据驱动创作策略实践
  • 宇舶服务项目及价格查询|网点地址与售后服务热线权威信息通知(2026年7月最新) - 亨得利官方服务中心
  • 寻找免垫密封胶供应商?这3点教你识别专业厂家
  • 基于CNN的水果成熟度智能检测系统设计与实现
  • 文心一言图片生成参数终极对照表,对比3大模型(SDXL/即梦/文心)的CFG/Steps/Clip Skip参数等效换算公式
  • 现代C++查找算法深度解析:从线性、二分到哈希与树的实战选型指南
  • 对称目标函数ICP:提升点云配准鲁棒性的双向匹配算法
  • 天津宝坻区宝平街道亨得利名表服务中心电话公示(2026年7月最新) - 亨得利官方