个人博客 www.tothefor.com 蓝桥杯复习知识点汇总
纸上得来终觉浅,绝知此事要躬行。路漫漫其修远兮,吾将上下而求索!知识是经过历史的巨人沉淀下来的,别总想着自己能够快速学会,多花点时间去看看,也许会发现些不同的东西。你能快速学会的、觉得简单的东西,对于别人来说也是一样的。人外有人,天外有天。当努力到达了一定的程度,幸运自会与你不期而遇。
目录
提示:n表示点数,m表示边数。
练习题目
Prim
朴素版Prim
适用于稠密图。时间复杂度:O(n2)
核心思想:每次挑一条与当前集合相连的最短边。
最短边的定义为:取当前点和集合中所有点比较后的最短距离。
import java.io.*;
import java.math.BigInteger;
import java.util.*;
public class Main {
public static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
public static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
public static StreamTokenizer cin = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
public static PrintWriter cout = new PrintWriter(new OutputStreamWriter(System.out));
public static Scanner sc = new Scanner(System.in);
public static int maxd = 200000+7;
public static int INF = 0x3f3f3f3f;
public static int mod = (int) 1e9+7;
public static int[] dis = new int[maxd];
public static int[] head = new int[maxd];
public static int[] edgePre = new int[maxd<<1];
public static int[] edgeW = new int[maxd<<1];
public static int[] edgeTo = new int[maxd<<1];
public static boolean[] vis = new boolean[maxd];
public static int n;
public static int node=0;
public static void add_edge(int a,int b,int c){
edgeTo[node] = b;
edgeW[node] = c;
edgePre[node] = head[a];
head[a]=node++;
}
public static void init(int n){
for(int i=0;i<=n;++i){
dis[i]=INF;
vis[i]=false;
head[i] = -1;
}
}
public static int Prim(){
int res = 0;
for(int i=1;i<=n;++i){
int t = -1;
for(int j=1;j<=n;++j){
if(!vis[j] && (t==-1 || dis[t]>dis[j]))
t = j;
}
vis[t]=true;
if(i!=1 && dis[t]==INF) return INF;
if(i!=1) res+=dis[t];
for(int j=head[t];j!=-1;j=edgePre[j]){
int to = edgeTo[j];
dis[to] = Math.min(dis[to],edgeW[j]);
}
}
return res;
}
public static void main(String[] args) throws Exception {
n = nextInt();
int m = nextInt();
init(n);
while(m-->0){
int a = nextInt();
int b = nextInt();
int c = nextInt();
add_edge(a,b,c);
add_edge(b,a,c);
}
int ans = Prim();
cout.println(ans==INF? "orz":ans);
cout.flush();
closeAll();
}
public static void cinInit(){
cin.wordChars('a', 'z');
cin.wordChars('A', 'Z');
cin.wordChars(128 + 32, 255);
cin.whitespaceChars(0, ' ');
cin.commentChar('/');
cin.quoteChar('"');
cin.quoteChar('\'');
cin.parseNumbers();
}
public static int nextInt() throws Exception{
cin.nextToken();
return (int) cin.nval;
}
public static long nextLong() throws Exception{
cin.nextToken();
return (long) cin.nval;
}
public static double nextDouble() throws Exception{
cin.nextToken();
return cin.nval;
}
public static String nextString() throws Exception{
cin.nextToken();
return cin.sval;
}
public static void closeAll() throws Exception {
cout.close();
in.close();
out.close();
}
}
堆优化Prim
时间复杂度 O(m*logn)。
import java.io.*;
import java.math.BigInteger;
import java.util.*;
public class Main {
public static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
public static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
public static StreamTokenizer cin = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
public static PrintWriter cout = new PrintWriter(new OutputStreamWriter(System.out));
public static Scanner sc = new Scanner(System.in);
public static int maxd = 200000+7;
public static int INF = 0x3f3f3f3f;
public static int mod = (int) 1e9+7;
public static int[] dis = new int[maxd];
public static int[] head = new int[maxd];
public static int[] edgePre = new int[maxd<<1];
public static int[] edgeW = new int[maxd<<1];
public static int[] edgeTo = new int[maxd<<1];
public static boolean[] vis = new boolean[maxd];
public static int n;
public static int node=0;
public static class Edge implements Comparable<Edge> {
private int to;
private int w;
Edge(int to, int w) {
this.to = to;
this.w = w;
}
public int compareTo(Edge obj) {
return this.w - obj.w;
}
}
public static void add_edge(int a,int b,int c){
edgeTo[node] = b;
edgeW[node] = c;
edgePre[node] = head[a];
head[a]=node++;
}
public static void init(int n){
for(int i=0;i<=n;++i){
dis[i]=INF;
vis[i]=false;
head[i] = -1;
}
}
public static int Prim(){
PriorityQueue<Edge> q = new PriorityQueue<Edge>();
int res = 0;
int cnt = 0;
q.add(new Edge(1,0));
while(!q.isEmpty()){
Edge u = q.poll();
if(vis[u.to]) continue;
vis[u.to] = true;
res+=u.w;
cnt++;
for(int i=head[u.to];i!=-1;i=edgePre[i]){
if(dis[u.to]>edgeW[i]){
q.add(new Edge(edgeTo[i],edgeW[i]));
}
}
}
if(cnt<n) return INF;
return res;
}
public static void main(String[] args) throws Exception {
n = nextInt();
int m = nextInt();
init(n);
while(m-->0){
int a = nextInt();
int b = nextInt();
int c = nextInt();
add_edge(a,b,c);
add_edge(b,a,c);
}
int ans = Prim();
cout.println(ans==INF? "orz":ans);
cout.flush();
closeAll();
}
public static void cinInit(){
cin.wordChars('a', 'z');
cin.wordChars('A', 'Z');
cin.wordChars(128 + 32, 255);
cin.whitespaceChars(0, ' ');
cin.commentChar('/');
cin.quoteChar('"');
cin.quoteChar('\'');
cin.parseNumbers();
}
public static int nextInt() throws Exception{
cin.nextToken();
return (int) cin.nval;
}
public static long nextLong() throws Exception{
cin.nextToken();
return (long) cin.nval;
}
public static double nextDouble() throws Exception{
cin.nextToken();
return cin.nval;
}
public static String nextString() throws Exception{
cin.nextToken();
return cin.sval;
}
public static void closeAll() throws Exception {
cout.close();
in.close();
out.close();
}
}
Kruskal
适用于稀疏图,时间复杂度 O(m*logm)。
import java.io.*;
import java.math.BigInteger;
import java.util.*;
public class Main {
public static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
public static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
public static StreamTokenizer cin = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
public static PrintWriter cout = new PrintWriter(new OutputStreamWriter(System.out));
public static Scanner sc = new Scanner(System.in);
public static int maxd = 200000+7;
public static int INF = 0x3f3f3f3f;
public static int mod = (int) 1e9+7;
public static int[] par = new int[maxd];
public static int n;
public static class Edge implements Comparable<Edge> {
private int u;
private int v;
private int w;
public Edge(int u, int v, int w) {
this.u = u;
this.v = v;
this.w = w;
}
public int compareTo(Edge obj) {
return this.w - obj.w;
}
}
public static Edge[] edges = new Edge[maxd<<1];
public static void init(int n,int m){
for(int i=1;i<=n;++i){
par[i] = i;
}
}
public static int find(int x){
if(x!=par[x]) par[x]=find(par[x]);
return par[x];
}
public static void unite(int a,int b){
int aa = find(a);
int bb = find(b);
if(aa!=bb) {
par[aa]=bb;
}
}
public static int Kruskal(int m){
int res = 0;
int cnt = 0;
Arrays.sort(edges,0,m);
for(int i=0;i<m;++i){
int u = edges[i].u;
int v = edges[i].v;
int w = edges[i].w;
if(find(u)!=find(v)){
unite(u,v);
res+=w;
cnt++;
}
}
if(cnt<n-1) return INF;
else return res;
}
public static void main(String[] args) throws Exception {
n = nextInt();
int m = nextInt();
init(n,m);
for(int i=0;i<m;++i){
int a = nextInt();
int b = nextInt();
int c = nextInt();
edges[i] = new Edge(a,b,c);
}
int ans = Kruskal(m);
cout.println(ans==INF? "orz":ans);
cout.flush();
closeAll();
}
public static void cinInit(){
cin.wordChars('a', 'z');
cin.wordChars('A', 'Z');
cin.wordChars(128 + 32, 255);
cin.whitespaceChars(0, ' ');
cin.commentChar('/');
cin.quoteChar('"');
cin.quoteChar('\'');
cin.parseNumbers();
}
public static int nextInt() throws Exception{
cin.nextToken();
return (int) cin.nval;
}
public static long nextLong() throws Exception{
cin.nextToken();
return (long) cin.nval;
}
public static double nextDouble() throws Exception{
cin.nextToken();
return cin.nval;
}
public static String nextString() throws Exception{
cin.nextToken();
return cin.sval;
}
public static void closeAll() throws Exception {
cout.close();
in.close();
out.close();
}
}
|