图论(洛谷刷题)

目录

前言:

题单:

P3386 【模板】二分图最大匹配

P1525 [NOIP2010 提高组] 关押罪犯

P3385 【模板】负环

P3371 【模板】单源最短路径(弱化版) 

SPFA写法

Dij写法:

 P3385 【模板】负环

P5960 【模板】差分约束 

 P7771 【模板】欧拉路径

文末: 


前言:

若刚入门图论,想做基础图论题,请移步:CSDN

题单:

P3386 【模板】二分图最大匹配

https://www.luogu.com.cn/problem/P3386

交替路:

从未匹配点出发,依次经过非匹配边,匹配边,非匹配边……形成的路径


增广路:

从非匹配点出发,走交替路,最后到达另一非匹配点的路径


算法:
可以发现增广路的匹配边比交替路的匹配边多一----->可以尽可能找增广路(用DFS或者BFS实现),当找不到增广路时,就得到了最大匹配边


匈牙利算法:

男女相亲,男选女,可占可让(可以有女朋友,当遍历到的男生的心仪女生有男朋友时,如果该男朋友还有其他心仪女生没有对象,那么该男朋友会将女朋友让出来,并有新的女朋友)😦😦😦(真渣啊~(*  ̄︿ ̄)(超小声嘀咕(* ̄3 ̄)╭))

const int N = 505;
const int M = 5e4 + 5;int cnt;
int head[N];
int match[N];//i的男友
int vis[N];int n, m, e;
int ans;struct EDGE
{int v;int next;
}EDGE[/*2 * */M];void add(int u, int v)
{cnt++;EDGE[cnt].v = v;EDGE[cnt].next = head[u];//不是等于cnthead[u] = cnt;
}bool dfs(int f)//boyfriend
{for (int i = head[f]; i; i = EDGE[i].next)//遍历女友{int v = EDGE[i].v;if (vis[v])continue;vis[v] = 1;if (match[v] == 0 || dfs(match[v]/*传的是男友*/)){match[v] = f;return 1;}}return 0;
}int main()
{quickio;cin >> n >> m >> e;int u, v;while (e--){cin >> u >> v;add(u, v);//add(v, u);//不要建双边,只要遍历男友就可以了}for (int i = 1; i <= n; i++)//遍历男友{memset(vis, 0, sizeof(vis));if (dfs(i))ans++;}cout << ans << endl;return 0;
}

P1525 [NOIP2010 提高组] 关押罪犯

https://www.luogu.com.cn/problem/P1525

思路:

要用到贪心

按边从大到小排序,再按顺序往后安排各自的监狱,首先最大的怨气的两个人肯定要放在不同的监狱(就是不同的集合---->要涉及到并查集,放相同监狱的有相同的祖先)🧐🧐🧐


#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <deque>
#include <functional>
#include <climits>#define quickio ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define endl "\n"using namespace std;
typedef long long ll;const int N = 2e4 + 5;
const int M = 1e5 + 5;int n, m;
int fa[N * 2];//> n的存的是敌人struct zf
{int a;int b;int c;
}zf[M];bool cmp(struct zf a, struct zf b)
{return a.c > b.c;
}int find(int x)
{if (fa[x] == x)return x;return fa[x] = find(fa[x]);
}int FindMin()
{for (int i = 0; i < m; i++){int x = find(zf[i].a);int y = find(zf[i].b);if (x == y)return zf[i].c;fa[fa[zf[i].a]]/*注意是fa[fa[]],要把祖先直接归并到敌人集合,而不只是自己*/ = find(zf[i].b + n)/*不是fa[zf[i].b + n],因为要找的是最上面的祖先*/;fa[fa[zf[i].b]] = find(zf[i].a + n);}return 0;
}int main()
{cin >> n >> m;//并查集基本操作:初始化父亲for (int i = 1; i <= 2 * n; i++)fa[i] = i;for (int i = 0; i < m; i++){cin >> zf[i].a >> zf[i].b >> zf[i].c;}sort(zf, zf + m, cmp);int ans = 0;ans = FindMin();cout << ans << endl;return 0;
}

P3385 【模板】负环

https://www.luogu.com.cn/problem/P3385

注意:

该题不可以用Dijkstra,只能用SPFA,但是通常求最短路最好用Dijkstra,因为SPFA经常被卡,例如你可以做这两个题目:😏  ......~( ̄▽ ̄)~*

【模板】单源最短路径(弱化版) - 洛谷

【模板】单源最短路径(标准版) - 洛谷

你会发现SPFA的代码可以过弱化版,但是过标准版会有一堆TLE(我会在后面公布这两题的答案ฅʕ•̫͡•ʔฅ)

P3371 【模板】单源最短路径(弱化版) 

【模板】单源最短路径(弱化版) - 洛谷

SPFA写法
//SPFA
//该代码是可以判断负环的SPFA,且采用vector存边#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <deque>
#include <functional>
#include <climits>#define quickio ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define endl "\n"using namespace std;
typedef long long ll;const int N = 5e5 + 5;struct edge
{int v;int w;
};
int vis[N];//标记是否在队内,所有pop后要置为0,和Dij不一样!!!!!!!!,Dij是标记该点访问过,不再访问
int ans[N];
int countt[N];//经过每个点的次数,如果有一个点的次数 >= n,则有负环vector<edge>e[N];int n, m, s;bool SPFA(int s)
{queue<int>que;//memset(ans, 0x3f, sizeof(ans));该题初始化为这个不够,0x3f3f3f3f < INT_MAX,要初始化为INT_MAX//注意题目要求啊!!!!!!!若不能到达则输出 2^31 - 1,for (int i = 1; i <= n; i++)ans[i] = INT_MAX;ans[s] = 0;que.push(s);vis[s] = 1;while (!que.empty()){int dian = que.front();que.pop();vis[dian] = 0;/*出队是0,注意!!!!!!!!!!,vis是表示是否在队内的*/for (auto ed : e[dian]){int v = ed.v;int w = ed.w;if (ans[v] > ans[dian] + w){ans[v] = ans[dian] + w;countt[v] = countt[dian] + 1;if (countt[v] >= n)return true;//返回true表示有负环if (vis[v] == 0){vis[v] = 1;que.push(v);}}}}return false;
}int main()
{cin >> n >> m >> s;int u, v, w;for (int i = 0; i < m; i++){cin >> u >> v >> w;e[u].push_back({ v, w });}SPFA(s);for (int i = 1; i <= n; i++)cout << ans[i] << " ";return 0;
}
Dij写法:

问题:

弱化版的代码超时---->要用堆优化   (ง •_•)ง

核心:

priority_queue< pair<int,int> > 用优先队列来取最近的点,就不用遍历找点了

在priority_queue中,是按pair的第一个元素(first)由大到小排序的,所以pair<距离,点号>,注意因为要的是最小值,所以距离要存负值 (重点敲黑板哦~~    😳😳😳)


总结:

要优先队列来方便选出最短路径,注意堆优化(优先队列)中的排序是从大到小,所以存距离要存负数
要一个结构体存每个点的数据,head数组存每条链的数据,还要用ans数组记录从起点到某点的最短距离,用vis数组记录点是否被加入过最短路径,避免重复加入


#include <queue>
/*堆优化:利用优先队列,降低复杂度,直接排序,注意优先队列是由大到小排列的,因此距离是负数 */
#include <climits>
#include <iostream>using namespace std;const int MAX = 1e6;
int n, m, s;
int ans[MAX];//最短距离
int cnt;
int head[MAX];//出边的头标记
int visit[MAX];//标记该点是否被访问过struct EDGE
{int to;int next;//下一个出边int wei;//权值
}edge[MAX];void add(int u, int v, int w)
{cnt++;edge[cnt].wei = w;edge[cnt].to = v;edge[cnt].next = head[u];head[u] = cnt;
}int main()
{int i;int u, v, w;cin >> n >> m >> s;for (i = 1; i <= n; i++)ans[i] = INT_MAX;ans[s] = 0;for (i = 1; i <= m; i++){cin >> u >> v >> w;add(u, v, w);}priority_queue<pair<int, int> >que;//距离,点que.push({0, s});while (!que.empty()){int qh = que.top().first;int h = que.top().second;que.pop();/*记得pop()!!!!!!!!!*/if (visit[h] == 0){visit[h] = 1;for (i = head[h]; i != 0; i = edge[i].next)//不断找下一个儿子,直到找完{if (ans[edge[i].to] > ans[h] + edge[i].wei){ans[edge[i].to] = ans[h] + edge[i].wei;if (visit[edge[i].to] == 0)que.push({ -ans[edge[i].to], edge[i].to });}}}}for (i = 1; i <= n; i++)cout << ans[i] << ' ';cout << endl;return 0;
}

 P3385 【模板】负环

P3385 【模板】负环 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

//负环
//该代码是可以判断负环的SPFA,且采用vector存边const int N = 5e5 + 5;struct edge
{int v;int w;
};
int vis[N];//标记是否在队内,所有pop后要置为0,和Dij不一样!!!!!!!!,Dij是标记该点访问过,不再访问
int ans[N];
int countt[N];//经过每个点的次数,如果有一个点的次数 >= n,则有负环vector<edge>e[N];int n, m, s;bool SPFA(int s)
{queue<int>que;for (int i = 1; i <= n; i++)ans[i] = INT_MAX;memset(vis, 0, sizeof(vis));memset(countt, 0, sizeof(countt));ans[s] = 0;que.push(s);vis[s] = 1;while (!que.empty()){int dian = que.front();que.pop();vis[dian] = 0;/*出队是0,注意!!!!!!!!!!,vis是表示是否在队内的*/for (auto ed : e[dian]){int v = ed.v;int w = ed.w;if (ans[v] > ans[dian] + w){ans[v] = ans[dian] + w;countt[v] = countt[dian] + 1;if (countt[v] >= n)return true;//返回true表示有负环if (vis[v] == 0){vis[v] = 1;que.push(v);}}}}return false;
}int main()
{int t;cin >> t;while (t--){memset(e, 0, sizeof(e));cin >> n >> m;int u, v, w;for (int i = 0; i < m; i++){cin >> u >> v >> w;if (w >= 0){e[u].push_back({ v, w });e[v].push_back({ u, w });}elsee[u].push_back({ v, w });}if (SPFA(1)){cout << "YES" << endl;}elsecout << "NO" << endl;}return 0;
}

P5960 【模板】差分约束 

【模板】差分约束 - 洛谷

一个差分约束系统是这样的:

给出 n 个变量和 m 个约束条件,形如    Xi - Xj≤Ck  ​,你需要求出一组解,使得所有约束条件均被满足。🤯🤯🤯

怎样解这个差分约束系统呢?我们将上面的不等式变形一下:

Xi​≤Xj​+Ck​          🤔(+_+)?

容易发现这个形式和最短路中的三角形不等式Dis(v)​≤Dis(u)​+w 非常相似。😮😮😮

因此我们就将这个问题转化为一个求最短路的问题:比如对于上面这个不等式,

1、我们从 j 向 i 连一条权值为 Ck​ 的边。

2、我们再新建一个 0 号点,从 0 号点向其他所有点连一条权值为 0的边。

这个操作相当于新增了一个变量 X0​ 和 n 个约束条件xi​≤x0​,从而将所有变量都和X0​ 这一个变量联系起来。

3、然后以 0号点为起点,用 SPFA 跑最短路。

如果有负权环,差分约束系统无解。否则设从 0号点到 i号点的最短路为 Dis(i)​,则xi​=Dis(i)​ 即为差分约束系统的一组可行解。

const int N = 5e5 + 5;struct edge
{int v;int w;
};
int vis[N];//标记是否在队内,所有pop后要置为0,和Dij不一样!!!!!!!!,Dij是标记该点访问过,不再访问
int ans[N];
int countt[N];//经过每个点的次数,如果有一个点的次数 >= n,则有负环vector<edge>e[N];int n, m, s;bool SPFA(int s)
{queue<int>que;for (int i = 1; i <= n; i++)ans[i] = INT_MAX;memset(vis, 0, sizeof(vis));memset(countt, 0, sizeof(countt));ans[s] = 0;que.push(s);vis[s] = 1;while (!que.empty()){int dian = que.front();que.pop();vis[dian] = 0;/*出队是0,注意!!!!!!!!!!,vis是表示是否在队内的*/for (auto ed : e[dian]){int v = ed.v;int w = ed.w;if (ans[v] > ans[dian] + w){ans[v] = ans[dian] + w;countt[v] = countt[dian] + 1;if (countt[v] >= n + 1/*注意这里是n + 1了,因为多加了一个0号节点*/)return true;//返回true表示有负环if (vis[v] == 0){vis[v] = 1;que.push(v);}}}}return false;
}int main()
{memset(e, 0, sizeof(e));cin >> n >> m;int u, v, w;for (int i = 0; i < m; i++){cin >> u >> v >> w;//e[u].push_back({ v, w });e[v].push_back({ u, w });//注意这里的起点和终点!!!!!!!}for (int i = 1; i <= n; i++)e[0].push_back({ i, 0 });//注意:要让一点可以到达所有点才行,但是图内不一定存在这种点,所以可以自己创建一个0节点,并和所有点都连起来,同时边权为0if (SPFA(0) == false)//从0号节点出发,求它到所有点的最短路径,如果有负环,该差分约束无解{for (int i = 1; i <= n; i++)cout << ans[i] << " ";cout << endl;}elsecout << "NO" << endl;return 0;
}

 P7771 【模板】欧拉路径

https://www.luogu.com.cn/problem/P7771

欧拉路径:

只经过一次的边😮


欧拉回路:

经过欧拉路径能回到起点的回路 🤨🤨🤨


欧拉图:

有欧拉 回路 的图😶


半欧拉图:

有欧拉 路径 的图,但是没有欧拉 回路 😵😵😵

判断是否有欧拉路径:
1、有向图
欧拉路径:
只有两个点出度不等于入度:起点(出度 = 入度 + 1),终点(入度 = 出度 + 1)
其他点:入度 = 出度 (~﹃~)~zZ
欧拉回路:
所有点入度等于出度 O_O

2、无向图
欧拉路径:
只有两个点的度数为奇数:起点(出度 = 入度 + 1),终点(入度 = 出度 + 1)
其他点:度数为偶数           (っ´Ι`)っ:偶数
欧拉回路:
所有点度数为偶数    ( ´・・)ノ(._.`)

const int N = 1e5 + 5;
const int M = 2e5 + 5;//用Dij不好排序,用vector的图
//struct EDGE
//{
//	int v;
//	int w;
//	int next;
//}EDGE[M];
//
//int head[N];
//int ans[N];
//int vis[N];
//int cnt;
//
//int du[N][2];//入度,出度
//
//void add(int u, int v, int w)
//{
//	cnt++;
//	EDGE[cnt].v = v;
//	EDGE[cnt].w = w;
//	EDGE[cnt].next = head[u];
//	head[u] = cnt;
//}vector<int>G[N];
stack<int>st;
int du[N][2];//入度,出度
int cnt[2];//记录多少点出度不等于入度,cnt[0]:入度 > 出度,cnt[1]:出度 > 入度
int beginn[N];//记录每个点遍历到了哪个出边void DFS(int qi)
{for (int i = beginn[qi]; i < G[qi].size(); i = beginn[qi]/*注意不是i++,因为经过DFS后,beginn[qi]的值可能早已改变,不能再从目前点的后一个点继续走*/){beginn[qi] = i + 1;DFS(G[qi][i]);}st.push(qi);//最后放:因为栈是先进后出,要先把该点的出边都遍历完再放入该点,以便输出时该点先输出
}int main()
{int n, m;cin >> n >> m;int u, v;for (int i = 0; i < m; i++){cin >> u >> v;G[u].push_back(v);du[u][1]++;du[v][0]++;}int qi = 1;//起点//int flag = 0;//flag = 0表示:所有点入度 = 出度for (int i = 1; i <= n; i++){sort(G[i].begin(), G[i].end());//注意vector和数组对sort的用法不同if (du[i][0] != du[i][1]){//flag = 1;if (du[i][0] - du[i][1] == 1)//入度 - 出度 = 1:终点{cnt[1]++;}else if (du[i][1] - du[i][0] == 1)//出度 - 入度 = 1:起点{cnt[0]++;qi = i;}else{cout << "No" << endl;return 0;}}}if (cnt[0] != cnt[1]/*起点数不等于终点数*/){cout << "No" << endl;return 0;}if (cnt[0] != 0/*不是欧拉路径*/ && cnt[0] != 1/*不止一个起点*/){cout << "No" << endl;return 0;}DFS(qi);while (!st.empty()){cout << st.top() << " ";st.pop();}return 0;
}

 

文末: 

单源最短路径(弱化版)

【模板】单源最短路径(弱化版) - 洛谷

该题可用Dij,也可用SPFA,该题SPFA可以:

单源最短路径(标准版) 

【模板】单源最短路径(标准版) - 洛谷

该题只能Dij,若为SPFA:

综上所述:最好用Dij算法求单源最短路径,但若有负边权只能用SPFA 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/835589.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker 容器中 PHP 使用 Curl 访问本地服务异常

在 Docker 环境中&#xff0c;将应用程序和服务容器化是常见的做法&#xff0c;但是有时会遇到一些网络通信方面的问题。其中一个常见的问题是 PHP 容器无法使用 Curl 访问本地服务&#xff0c;这可能导致开发和调试过程中的困扰。 问题描述 通常情况下&#xff0c;我们会将 …

系统代理开启时,钉钉页面加载失败等问题处理

若Windows端钉钉点击工作台/文件提示“页面加载失败”&#xff0c;可先将钉钉升级到7.1.10及以上版本&#xff1b;若依旧报错&#xff0c;可通过以下方法操作&#xff1a; 1、【电脑端钉钉】-【登录页面】-【切换到密码登录页面】-【网络设置】-切换为【不使用代理】&#xff…

mysql NDBcluster数据库集群介绍、部署及配置

前言: MySQL集群是一个无共享的、分布式节点架构的存储方案,旨在提供容错性和高性能。它由三个主要节点组成:管理节点(MGM)、数据节点和SQL节点。 管理节点(MGM) 定义与用途:管理节点是MySQL Cluster的控制中心,负责管理集群内的其他节点。它提供配置数据,启动和停止…

UE5 重定向时 APose和TPose 问题

我用了这个解决↓ IK Rig Animation Retargeting in Unreal Engine | Unreal Engine 5.0 Documentation | Epic Developer Community (epicgames.com) 这个可以参考↓ 虚幻引擎中的重定向管理器 |虚幻引擎 5.0 文档 |Epic开发者社区 (epicgames.com)

AI伦理和安全风险管理终极指南

人工智能&#xff08;AI&#xff09;正在迅速改变各个领域的软件开发和部署。驱动这一转变的两个关键群体为人工智能开发者和人工智能集成商。开发人员处于创建基础人工智能技术的最前沿&#xff0c;包括生成式人工智能&#xff08;GenAI&#xff09;模型、自然语言处理&#x…

ASP.NET网上鲜花销售系统的设计

摘 要 本系统实现了一般电子商务所具备的功能&#xff0c;如商品浏览、用户登录注册、网上与购物、结算、后台数据库管理等&#xff0c;利用这些功能可以对鲜花销售信息进行较好的管理。 网上鲜花销售系统的使用者主要是客户和销售管理者&#xff0c;对于客户来说&#xff0…

利用一下Chat-GPT写两段处理字符串的简单样例ABAP程序。这样可以大大提高工作效率。Chat-GPT的能力真是让人震撼。

我让Caht-GPT写两段ABAP 程序&#xff0c;第一段程序要求如下&#xff1a; 判读字符串里面是否含有特殊字符&#xff0c;这里说的特殊字符不包括键盘上能够输入的字符&#xff0c;如果有这样的特殊字符则输出来。 DATA: lv_string TYPE string VALUE 你的字符串,lv_result TYP…

测试开发之Python自动化 Pytest 之 fixture

Pytest 之 fixture unittest 和 nose 都支持 fixture 的,但是 fixture 在 pytest 里使用更灵活。也算是 pytest 的一个闪光点吧可以理解为一个跟 setup 和 teardown 这种前后置类似的东西。但是比它们要强大、灵活很多 fixtur 当做参数传入 # -*- coding: utf-8 -*- import …

SSL证书 购买流程

在购买SSL证书之前&#xff0c;需要知道一点相关的知识&#xff0c;通常包括以下几个环节&#xff1a; 一、确定需求 1、根据需要保护的域名数量&#xff0c;在以下三类中选择合适的证书类型&#xff1a; 单域名证书&#xff0c;只对一个域名&#xff08;例如abc.com&#x…

设计软件有哪些?渲染软件篇(4),渲染100邀请码1a12

除了之前介绍的一些渲染软件&#xff0c;这次我们继续介绍。 1、渲染100(http://www.xuanran100.com/?ycode1a12) 渲染100是网渲平台&#xff0c;为设计师提供高性能的渲染服务。通过它设计师可以把本地渲染移到云端进行&#xff0c;速度快价格便宜&#xff0c;支持3dmax、v…

数据序列包分析

基于数据序列包分析各部分的内容及含义&#xff0c;可能会考大题 基于本例分析&#xff0c;每部分含义如下&#xff1a; 时间&#xff08;Time&#xff09;&#xff1a; 时间戳显示了数据包在网络中被捕获的具体时间。在本例中&#xff0c;如"0.000000"表示第一个数据…

视频批量剪辑指南:一键合并视频并添加背景音乐,高效便捷

在数字化时代&#xff0c;视频剪辑已经成为了一项常见且重要的技能。无论是制作家庭影片、工作展示还是社交媒体内容&#xff0c;掌握高效的视频剪辑技巧都能极大地提升我们的工作效率和创作质量。本文将为您介绍云炫AI智剪中高效的视频批量剪辑方法&#xff0c;让您能够一键合…

虚拟机ubuntu配置网络重启联网

前言 一段时间没用虚拟机&#xff0c;打开发现网络一直连接不上【如下图】 flags4099<UP,BROADCAST,MULTICAST> mtu 1500inet 172.18.0.1 netmask 255.255.0.0 broadcast 172.18.255.255ether 02:42:c2:5b:60:75 txqueuelen 0 (Ethernet)原因 1.以为是网络适配器选…

Ubuntu24.04安装中文输入法

Ubuntu24.04安装中文输入法 为了更好的体验&#xff0c;请访问个人博客 www.huerpu.cc:7000 一、添加中文语言支持 在安装中文输入法之前&#xff0c;首选要添加中文语言支持。选择System&#xff0c;点击Region & Language。 点击Manage Install Languages。 点击Insta…

更专业的汽车软件研发工具链,怿星重磅发布新产品

怿星科技在2024北京国际车展同期举办主题为“创新引领未来——聚焦智能汽车软件新基建”的新产品发布会&#xff0c;重磅推出1款绝对优势产品和4套场景解决方案。同时举行了4场热点技术研讨&#xff1a;国产工具链的机遇与挑战、新架构下的的车载DDS应用探索及测试方案介绍、软…

Linux 安裝 rpm包

下载 地址&#xff1a;https://developer.aliyun.com/packageSearch 安装 rpm -ivh lsof-4.87-6.el7.x86_64.rpmlsof -Ki|awk {print $2}|sort|uniq -c|sort -nr|head lsof | wc -l

vue2中npm i报错gyp info it worked if it ends with ok

当我拿到一个老的vue2项目&#xff0c;怎么也起不起来&#xff0c;后来找到报错原因&#xff0c;如上图所示&#xff0c;可以看到报错的path是node-sass&#xff0c;那么就猜想应该是sass版本和node版本不匹配。 于是我查看了我的node版本是16 而sass版本是下图所示&#xff0c…

itextpdf 7生成pdf(主要是文字和表格,支持中文)

我们经常会遇到要导出pdf的需求,方式有很多种 今天的教程是采用itextpdf的方式生成pdf itextpdf是用于生成PDF文档的一个java类库。通过iText不仅可以生成PDF文档&#xff0c;而且可以将Html文件转化为PDF文件。 这里先展示一下效果图 首先在pom.xml中引入相关依赖 <dep…

在 Navicat 17 创建一个数据字典

即将于 5 月 13 日发布的 Navicat 17&#xff08;英文版&#xff09;添加了许多令人兴奋的新功能。其中之一就是数据字典工具。它使用一系列 GUI 指导你完成创建专业质量文档的过程&#xff0c;该文档为跨多个服务器平台的数据库中的每个数据元素提供描述。在今天的博客中&…

Kotlin基本特性

目录 函数 if when 循环 面向对象 继承 主构造函数 接口 修饰符 ​编辑数据类 单例类 Lambda编程 集合 lambda用法 常见函数式API 空指针 判空辅助工具 字符串内嵌表达式 函数 fun add1(a:Int,b:Int):Int{return ab }fun add2(a:Int,b:Int):Int ab // 只…