PAT (Advanced Level) Practice 用到图的存储方式,但没有用到图的算法的题目

目录

  • 1122 Hamiltonian Cycle (25)
  • 1126 Eulerian Path (25)
  • 1134 Vertex Cover (25)
  • 1142 Maximal Clique (25)
  • 1154 Vertex Coloring (25)

1122 Hamiltonian Cycle (25)

题目思路

  • n != queryV.size() 检查是否 query 覆盖了所有结点
  • kn != n + 1 检查 query 是否多走或少走
  • query[0] != query[kn-1] 检查是否成环
  • 遍历 query 检查是否每一步都可到达
  1. #include<iostream>
  2. #include<unordered_set>
  3. using namespace std;
  4. bool G[201][201] = {false};
  5. int main()
  6. {
  7. int n, m, u, v, k, kn;
  8. scanf("%d%d", &n, &m);
  9. for (int i = 0; i < m; i++){
  10. scanf("%d%d", &u, &v);
  11. G[u][v] = G[v][u] = true;
  12. }
  13. scanf("%d", &k);
  14. for (int i = 0; i < k; i++){
  15. scanf("%d", &kn);
  16. int query[kn];
  17. unordered_set<int> queryV;
  18. for (int j = 0; j < kn; j++){
  19. scanf("%d", &query[j]);
  20. queryV.insert(query[j]);
  21. }
  22. bool isC = true;
  23. for (int j = 0; j < kn - 1; j++)
  24. if (!G[query[j]][query[j+1]]) isC = false;
  25. if (!isC || kn != n + 1 || n != queryV.size() || query[0] != query[kn-1]) printf("NO\n");
  26. else printf("YES\n");
  27. }
  28. return 0;
  29. }

1126 Eulerian Path (25)

题目思路

  • 用邻接表存储图,可以用每个结点对应邻接点的个数(Adj[i].size())表示每个结点的度
  • 题干给出根据度奇偶性和个数判断的先决条件是要是连通图
  • 先用深搜判断连通,从任一结点开始,看可以遍历到多少结点
  • 若遍历到的结点数与结点总数不同,则不是连通图,直接输出 Non-Eulerian
  • 若相同则说明是连通图,再遍历邻接表输出结点度数并记录度数为奇数的结点个数
  • 根据奇度数结点个数输出是否为 Eulerian
  1. #include<iostream>
  2. #include<vector>
  3. #include<queue>
  4. using namespace std;
  5. vector<int> Adj[501];
  6. bool vis[501] = {false};
  7. int connected = 0;
  8. void DFS(int root){
  9. connected++;
  10. vis[root] = true;
  11. for (int i = 0; i < Adj[root].size(); i++)
  12. if (!vis[Adj[root][i]]) DFS(Adj[root][i]);
  13. }
  14. int main()
  15. {
  16. int n, m, u, v, oddnum = 0;
  17. scanf("%d%d", &n, &m);
  18. for (int i = 0; i < m; i++){
  19. scanf("%d%d", &u, &v);
  20. Adj[u].push_back(v);
  21. Adj[v].push_back(u);
  22. }
  23. DFS(1);
  24. for (int i = 1; i < n + 1; i++){
  25. printf("%d%c", Adj[i].size(), i == n ? '\n' : ' ');
  26. if (Adj[i].size() % 2) oddnum++;
  27. }
  28. if (connected != n) printf("Non-Eulerian\n");
  29. else printf("%s\n", !oddnum ? "Eulerian" : oddnum == 2 ? "Semi-Eulerian" : "Non-Eulerian");
  30. return 0;
  31. }

简化前代码

  • 用邻接矩阵存储图
  • 单独开数组记录结点度数
  • 用 BFS 判断是否连通
  1. #include<iostream>
  2. #include<vector>
  3. #include<queue>
  4. using namespace std;
  5. int G[501][501] = {0};
  6. bool vis[501] = {false};
  7. int main()
  8. {
  9. int n, m, u, v, connected = 0, oddnum = 0;
  10. scanf("%d%d", &n, &m);
  11. int degree[n+1] = {0};
  12. for (int i = 0; i < m; i++){
  13. scanf("%d%d", &u, &v);
  14. degree[u]++;
  15. degree[v]++;
  16. G[u][v] = G[v][u] = 1;
  17. }
  18. queue<int> q;
  19. q.push(n);
  20. vis[n] = true;
  21. while (!q.empty()){
  22. int now = q.front();
  23. q.pop();
  24. connected++;
  25. for (int i = 1; i < n + 1; i++){
  26. if (!vis[i] && G[now][i]){
  27. q.push(i);
  28. vis[i] = true;
  29. }
  30. }
  31. }
  32. for (int i = 1; i < n + 1; i++){
  33. printf("%d%c", degree[i], i == n ? '\n' : ' ');
  34. if (degree[i] % 2) oddnum++;
  35. }
  36. if (connected != n) printf("Non-Eulerian\n");
  37. else printf("%s\n", !oddnum ? "Eulerian" : oddnum == 2 ? "Semi-Eulerian" : "Non-Eulerian");
  38. return 0;
  39. }

1134 Vertex Cover (25)

题目思路

  • vector<pair<int,int>> 保存边的端点
  • 对每个 query,新建一个 map 标记给出的 vertex
  • 遍历所有边,检查是否有边两个端点均不在给出的 vertex 中
  • 若有说明给出的 vertex 不能覆盖所有边,标记变量退出循环
  • 按标记变量输出要求内容
  1. #include<iostream>
  2. #include<vector>
  3. #include<unordered_map>
  4. using namespace std;
  5. int main()
  6. {
  7. int n, m, k, nv, v;
  8. scanf("%d%d", &n, &m);
  9. vector<pair<int,int>> edges(m);
  10. for (int i = 0; i < m; i++) scanf("%d%d", &edges[i].first, &edges[i].second);
  11. scanf("%d", &k);
  12. for (int i = 0; i < k; i++){
  13. scanf("%d", &nv);
  14. unordered_map<int,bool> vertex;
  15. bool iscover = true;
  16. for (int j = 0; j < nv; j++){
  17. scanf("%d", &v);
  18. vertex[v] = true;
  19. }
  20. for (int j = 0; j < m; j++){
  21. if (!vertex[edges[j].first] && !vertex[edges[j].second]){
  22. iscover = false;
  23. break;
  24. }
  25. }
  26. printf("%s\n", iscover ? "Yes" : "No");
  27. }
  28. return 0;
  29. }

1142 Maximal Clique (25)

题目思路

  • 输入无向边,用邻接矩阵将两个方向的边均存储起来
  • 每输入一个待检查的序列,就将标记变量 isclique & isMax 均设为 true,新建保存序列的数组和保存序列结点的集合
  • 输入待查序列同时将结点压入集合
  • 首先用二重循环检查序列是否两两相邻,若不是,说明现有序列非 clique,设置标记输出内容并跳出循环
  • 若通过上个检查,已知是 clique,要检查是否是最大的,也就是是否有其他结点与序列中每个点都相邻
  • 用一个变量按顺序遍历结点标号,取出不在序列中的结点,与序列结点两两配对检查是否相邻
    • 若有一对不相邻就从序列结点中 break 取下一个结点
    • 若能一直检查到序列结尾,发现此结点与序列每个结点均相邻,说明现有序列非 max clique,设置标记输出内容跳出循环
  • 最后检查变量按要求输出内容
  1. #include<iostream>
  2. #include<set>
  3. using namespace std;
  4. bool G[201][201] = {false};
  5. int main()
  6. {
  7. int nv, ne, u, v, m, K;
  8. scanf("%d%d", &nv, &ne);
  9. for (int i = 0; i < ne; i++){
  10. scanf("%d%d", &u, &v);
  11. G[u][v] = G[v][u] = true;
  12. }
  13. scanf("%d", &m);
  14. for (int i = 0; i < m; i++){
  15. bool isclique = true, isMax = true;
  16. scanf("%d", &K);
  17. int clique[K];
  18. set<int> cliqueV;
  19. for (int j = 0; j < K; j++){
  20. scanf("%d", &clique[j]);
  21. cliqueV.insert(clique[j]);
  22. }
  23. for (int j = 0; j < K - 1; j++){
  24. for (int k = j + 1; k < K; k++){
  25. if (!G[clique[j]][clique[k]]){
  26. isclique = false;
  27. printf("Not a Clique\n");
  28. break;
  29. }
  30. }
  31. if (!isclique) break;
  32. }
  33. if (isclique){
  34. for (int j = 1; j <= nv; j++){
  35. if (cliqueV.find(j) == cliqueV.end()){
  36. for (int k = 0; k < K; k++){
  37. if (!G[clique[k]][j]) break;
  38. if (k == K - 1) isMax = false;
  39. }
  40. }
  41. if (!isMax){
  42. printf("Not Maximal\n");
  43. break;
  44. }
  45. }
  46. if (isMax) printf("Yes\n");
  47. }
  48. }
  49. return 0;
  50. }

1154 Vertex Coloring (25)

题目思路

  • vector<pair<int,int>>保存所有边
  • 将所有点的颜色存起来,同时放入set统计颜色个数
  • 枚举所有边,检查是否每条边的两点个颜色是否相同
  • 若有相同的边,设置标记
  • 根据标记 输出颜色个数 或 输出No
  1. #include<iostream>
  2. #include<vector>
  3. #include<set>
  4. using namespace std;
  5. int main()
  6. {
  7. int n, m, k, u, v;
  8. scanf("%d%d", &n, &m);
  9. vector<pair<int,int>> edges(m);
  10. for (int i = 0; i < m; i++)
  11. scanf("%d%d", &edges[i].first, &edges[i].second);
  12. scanf("%d", &k);
  13. for (int i = 0; i < k; i++){
  14. vector<int> colors(n);
  15. set<int> coloring;
  16. bool isokay = true;
  17. for (int j = 0; j < n; j++){
  18. scanf("%d", &colors[j]);
  19. coloring.insert(colors[j]);
  20. }
  21. for (int j = 0; j < m; j++)
  22. if (colors[edges[j].first] == colors[edges[j].second])
  23. isokay = false;
  24. if (!isokay) printf("No\n");
  25. else printf("%d-coloring\n", coloring.size());
  26. }
  27. return 0;
  28. }

PAT甲级 图 相关题_C++题解的更多相关文章

  1. PAT甲级 Dijkstra 相关题_C++题解

    Dijkstra PAT (Advanced Level) Practice Dijkstra 相关题 目录 <算法笔记>重点摘要 1003 Emergency (25) <算法笔记 ...

  2. PAT甲级 二叉树 相关题_C++题解

    二叉树 PAT (Advanced Level) Practice 二叉树 相关题 目录 <算法笔记> 重点摘要 1020 Tree Traversals (25) 1086 Tree T ...

  3. PAT甲级 二叉查找树 相关题_C++题解

    二叉查找树 PAT (Advanced Level) Practice 二叉查找树 相关题 目录 <算法笔记> 重点摘要 1099 Build A Binary Search Tree ( ...

  4. PAT甲级 树 相关题_C++题解

    树 目录 <算法笔记>重点摘要 1004 Counting Leaves (30) 1053 Path of Equal Weight (30) 1079 Total Sales of S ...

  5. PAT甲级 堆 相关题_C++题解

    堆 目录 <算法笔记>重点摘要 1147 Heaps (30) 1155 Heap Paths (30) <算法笔记> 9.7 堆 重点摘要 1. 定义 堆是完全二叉树,树中每 ...

  6. PAT甲级 散列题_C++题解

    散列 PAT (Advanced Level) Practice 散列题 目录 <算法笔记> 重点摘要 1002 A+B for Polynomials (25) 1009 Product ...

  7. PAT甲级 字符串处理题_C++题解

    字符串处理题 目录 <算法笔记> 重点摘要 1001 A+B Format (20) 1005 Spell It Right (20) 1108 Finding Average (20) ...

  8. PAT甲级 图的遍历 相关题_C++题解

    图的遍历 PAT (Advanced Level) Practice 图的遍历 相关题 目录 <算法笔记>重点摘要 1021 Deepest Root (25) 1076 Forwards ...

  9. PAT甲级 并查集 相关题_C++题解

    并查集 PAT (Advanced Level) Practice 并查集 相关题 <算法笔记> 重点摘要 1034 Head of a Gang (30) 1107 Social Clu ...

随机推荐

  1. Ubuntu16.04 apache2+php7.0+mysql5.7环境搭建

    今天配置一下web环境,很常见的apache+php+mysql的网站环境: 步骤一:安装apache sudo apt install apache2 步骤二:安装php7 1.安装PHP7和响应的 ...

  2. 走进JavaWeb技术世界7:Tomcat中的设计模式

    . 门面设计模式 门面设计模式在 Tomcat 中有多处使用,在 Request 和 Response 对象封装中.Standard Wrapper 到 ServletConfig 封装中.Appli ...

  3. 使用python3安装frida-tools出错

    执行安装命令 pip3.6 install frida-tools 得到错误信息 error: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] c ...

  4. django + vue3 解决跨越问题

    django跨域 解决: https://yq.aliyun.com/articles/517215 vue3 跨越(此处没必要,django处理即可): https://blog.csdn.net/ ...

  5. What is the difference between XSS and CSRF from their execution perspective?

    What is the difference between XSS and CSRF from their execution perspective? https://www.quora.com/ ...

  6. python pip 安装插件权限问题及 指定pip国内镜像源

  7. python 简化数据结构的初始化二 支持关键字参数

    1.例子 学自cookbook3

  8. redis修改持久化路径、日志路径、清缓存

    redis修改持久化路径和日志路径 vim redis.conf logfile /data/redis_cache/logs/redis.log #日志路径 dir /data/redis_cach ...

  9. linux性能监控 -CPU、Memory、IO、Network等指标的讲解

    [操作系统-linux]linux性能监控 -CPU.Memory.IO.Network等指标的讲解(转) 一.CPU 1.良好状态指标 CPU利用率:User Time <= 70%,Syst ...

  10. NPM 私服

    下载https://nodejs.org/en/download/ linux binaries x64版本xz -d ....xztar -xvf ....tar导入path修改~/.bashrc加 ...